From 9b6a4c75b9040731609b562e6231f93712d8411a Mon Sep 17 00:00:00 2001 From: Blitblank Date: Tue, 10 Mar 2026 22:49:14 -0500 Subject: [PATCH] add crud to api --- api/Dockerfile | 1 + api/Program.cs | 57 +++++++++++----------- api/Properties/launchSettings.json | 10 ++-- api/agologum-api.csproj | 1 + api/agologum-api.http | 2 +- api/src/Controllers/UsersController.cs | 67 ++++++++++++++++++++++++++ api/src/Models/User.cs | 10 ++++ api/src/Stores/UserStore.cs | 46 ++++++++++++++++++ api/test.cs | 15 ------ client/src/api/UsersApi.ts | 16 +++--- client/src/components/UsersTable.vue | 4 +- client/src/pages/UsersList.vue | 4 +- 12 files changed, 172 insertions(+), 61 deletions(-) create mode 100644 api/src/Controllers/UsersController.cs create mode 100644 api/src/Models/User.cs create mode 100644 api/src/Stores/UserStore.cs delete mode 100644 api/test.cs diff --git a/api/Dockerfile b/api/Dockerfile index ca64b1e..41f3dfc 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -17,4 +17,5 @@ COPY --from=build /app/publish ./ EXPOSE 5000 +ENV ASPNETCORE_ENVIRONMENT="Production" ENTRYPOINT ["dotnet", "agologum-api.dll"] diff --git a/api/Program.cs b/api/Program.cs index 36d8d30..d0e4ce9 100644 --- a/api/Program.cs +++ b/api/Program.cs @@ -1,8 +1,13 @@ using Microsoft.AspNetCore.HttpOverrides; +using agologumApi.Stores; + var builder = WebApplication.CreateBuilder(args); +builder.Services.AddControllers(); +builder.Services.AddSingleton(); + // configuration for behind my nginx proxy builder.Services.Configure(options => { @@ -10,7 +15,7 @@ builder.Services.Configure(options => ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; - options.KnownNetworks.Clear(); + options.KnownIPNetworks.Clear(); options.KnownProxies.Clear(); }); @@ -18,42 +23,34 @@ builder.Services.Configure(options => // Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi builder.Services.AddOpenApi(); +builder.Services.AddCors(options => +{ + options.AddPolicy("dev", + policy => + { + policy.AllowAnyOrigin() + .AllowAnyHeader() + .AllowAnyMethod(); + }); +}); + +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + var app = builder.Build(); app.UseForwardedHeaders(); +app.UseCors("dev"); // Configure the HTTP request pipeline. -if (app.Environment.IsDevelopment()) -{ +if (app.Environment.IsEnvironment("Development")) { app.MapOpenApi(); + app.UseSwagger(); + app.UseSwaggerUI(); +} else { + app.UseHttpsRedirection(); } -app.UseHttpsRedirection(); - - -// below is a placeholder endpoint -var summaries = new[] -{ - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" -}; - -app.MapGet("api/weatherforecast", () => -{ - var forecast = Enumerable.Range(1, 5).Select(index => - new WeatherForecast - ( - DateOnly.FromDateTime(DateTime.Now.AddDays(index)), - Random.Shared.Next(-20, 55), - summaries[Random.Shared.Next(summaries.Length)] - )) - .ToArray(); - return forecast; -}) -.WithName("GetWeatherForecast"); +app.MapControllers(); app.Run(); - -record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) -{ - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); -} diff --git a/api/Properties/launchSettings.json b/api/Properties/launchSettings.json index f689500..841996f 100644 --- a/api/Properties/launchSettings.json +++ b/api/Properties/launchSettings.json @@ -1,23 +1,23 @@ { "$schema": "https://json.schemastore.org/launchsettings.json", "profiles": { - "http": { + "http-dev": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, - "applicationUrl": "http://localhost:5227", + "applicationUrl": "http://0.0.0.0:5227", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, - "https": { + "https-dev": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, - "applicationUrl": "https://localhost:7182;http://localhost:5227", + "applicationUrl": "https://0.0.0.0:7182;http://0.0.0.0:5227", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } - } + }, } } diff --git a/api/agologum-api.csproj b/api/agologum-api.csproj index bcac402..525cfa3 100644 --- a/api/agologum-api.csproj +++ b/api/agologum-api.csproj @@ -9,6 +9,7 @@ + diff --git a/api/agologum-api.http b/api/agologum-api.http index 39b8ff9..c422b39 100644 --- a/api/agologum-api.http +++ b/api/agologum-api.http @@ -1,4 +1,4 @@ -@agologum_api_HostAddress = http://localhost:5227 +@agologum_api_HostAddress = http://0.0.0.0:5227 GET {{agologum_api_HostAddress}}/weatherforecast/ Accept: application/json diff --git a/api/src/Controllers/UsersController.cs b/api/src/Controllers/UsersController.cs new file mode 100644 index 0000000..38cb664 --- /dev/null +++ b/api/src/Controllers/UsersController.cs @@ -0,0 +1,67 @@ + +using Microsoft.AspNetCore.Mvc; +using agologumApi.Models; +using agologumApi.Stores; + +[ApiController] +[Route("api/[controller]")] +public class UsersController : ControllerBase +{ + private readonly UserStore store_; + + public UsersController(UserStore store) + { + store_ = store; + } + + [HttpGet] + public ActionResult> getUsers() + { + return Ok(store_.getUsers()); + } + + [HttpGet("{id:int}")] + public ActionResult getUser(int id) + { + var user = store_.getUser(id); + + if (user == null) + return NotFound(); + + return Ok(user); + } + + [HttpPost] + public ActionResult createUser(User user) + { + var created = store_.createUser(user); + + return CreatedAtAction( + nameof(getUser), + new { id = created.Id }, + created + ); + } + + [HttpPut("{id}")] + public ActionResult updateUser(int id, User user) + { + var updated = store_.updateUser(id, user); + + if (updated == null) + return NotFound(); + + return Ok(updated); + } + + [HttpDelete("{id}")] + public ActionResult deleteUser(int id) + { + var success = store_.deleteUser(id); + + if (!success) + return NotFound(); + + return NoContent(); + } +} \ No newline at end of file diff --git a/api/src/Models/User.cs b/api/src/Models/User.cs new file mode 100644 index 0000000..b42e2d8 --- /dev/null +++ b/api/src/Models/User.cs @@ -0,0 +1,10 @@ + +namespace agologumApi.Models; + +public class User { + + public int Id { get; set; } + public string Name { get; set; } = ""; + public string Email { get; set; } = ""; + +}; diff --git a/api/src/Stores/UserStore.cs b/api/src/Stores/UserStore.cs new file mode 100644 index 0000000..456bf33 --- /dev/null +++ b/api/src/Stores/UserStore.cs @@ -0,0 +1,46 @@ + +// temporary state management +// this will eventually change into a service that uses EnitityFramework for database interactions + +using agologumApi.Models; + +namespace agologumApi.Stores; + +public class UserStore { + + private readonly List users_ = new(); + private int nextId_ = 1; + + public List getUsers() { + return users_; + } + + public User? getUser(int id) { + return users_.FirstOrDefault(x => x.Id == id); + } + + public User createUser(User user) { + user.Id = nextId_++; + users_.Add(user); + return user; + } + + public User? updateUser(int id, User updated) { + var existing = users_.FirstOrDefault(x => x.Id == id); + if(existing == null) return null; + + existing.Name = updated.Name; + existing.Email = updated.Email; + + return existing; + } + + public bool deleteUser(int id) { + var existing = users_.FirstOrDefault(x => x.Id == id); + if(existing == null) return false; + + users_.Remove(existing); + return true; + } + +} \ No newline at end of file diff --git a/api/test.cs b/api/test.cs deleted file mode 100644 index ed14715..0000000 --- a/api/test.cs +++ /dev/null @@ -1,15 +0,0 @@ - -// this is a test program for making sure your dotnet environment is working properly - -/* -using System.Diagnostics; -using System; - -Stopwatch sw = new Stopwatch(); -sw.Start(); -Console.WriteLine("Hi mom !"); -Console.WriteLine("doing a schmunguss"); -sw.Stop(); - -Console.WriteLine("Time elapsed: {0}", sw.Elapsed); -*/ diff --git a/client/src/api/UsersApi.ts b/client/src/api/UsersApi.ts index 6f33454..3c8d01b 100644 --- a/client/src/api/UsersApi.ts +++ b/client/src/api/UsersApi.ts @@ -7,14 +7,18 @@ import axios from "axios"; import type {AxiosResponse } from "axios"; import type { User } from "../models/User.ts"; -const API_URL: string = "/api/items"; +const API_URL: string = "/users"; -export const getUsers = () => axios.get(API_URL); +const api = axios.create({ + baseURL: "http://10.145.164.106:5227/api" +}); -export const getUser = (id: number) => axios.get(`${API_URL}/${id}`); +export const getUsers = () => api.get(`${API_URL}`); -export const createUser = (data: User) => axios.post(API_URL, data); +export const getUser = (id: number) => api.get(`${API_URL}/${id}`); -export const updateUser = (id: number, data: User) => axios.put(`${API_URL}/${id}`, data); +export const createUser = (data: User) => api.post(`${API_URL}`, data); -export const deleteUser = (id: number) => axios.delete(`${API_URL}/${id}`); +export const updateUser = (id: number, data: User) => api.put(`${API_URL}/${id}`, data); + +export const deleteUser = (id: number) => api.delete(`${API_URL}/${id}`); diff --git a/client/src/components/UsersTable.vue b/client/src/components/UsersTable.vue index 13c74cf..b9c87e0 100644 --- a/client/src/components/UsersTable.vue +++ b/client/src/components/UsersTable.vue @@ -17,13 +17,13 @@ onMounted(() => { // register callback for when component is loaded on page

Users

- Create User + Create User diff --git a/client/src/pages/UsersList.vue b/client/src/pages/UsersList.vue index 58036ca..627cc90 100644 --- a/client/src/pages/UsersList.vue +++ b/client/src/pages/UsersList.vue @@ -16,13 +16,13 @@ onMounted(() => {

Users

- Create User + Create User
{{ user.name }} - Edit + Edit
{{ user.name }} - Edit + Edit