Initial version

This commit is contained in:
2026-06-20 10:24:36 +02:00
parent f85b83d90f
commit 7e1173bf2c
40 changed files with 5438 additions and 63 deletions
@@ -0,0 +1,54 @@
using EonaCat.DoxaApi.Attributes;
using Microsoft.AspNetCore.Mvc;
using SampleApi.Models;
namespace SampleApi.Controllers
{
[ApiController]
[Route("api/orders")]
[DoxaApiGroup("Orders")]
public class OrdersController : ControllerBase
{
private static readonly List<Order> _orders = new();
[HttpGet]
public ActionResult<List<Order>> GetOrders()
=> Ok(_orders.OrderByDescending(o => o.PlacedAt).ToList());
[HttpGet("{id}")]
public ActionResult<Order> GetById(Guid id)
{
var order = _orders.FirstOrDefault(o => o.Id == id);
return order is null ? NotFound() : Ok(order);
}
[HttpPost]
public ActionResult<Order> Create([FromBody] CreateOrderRequest request)
{
var order = new Order
{
Id = Guid.NewGuid(),
UserId = request.UserId,
Lines = request.Lines,
Total = request.Lines.Sum(l => l.UnitPrice * l.Quantity),
Status = OrderStatus.Pending,
PlacedAt = DateTime.UtcNow
};
_orders.Add(order);
return CreatedAtAction(nameof(GetById), new { id = order.Id }, order);
}
[HttpPost("{id}/cancel")]
public ActionResult<Order> Cancel(Guid id)
{
var order = _orders.FirstOrDefault(o => o.Id == id);
if (order is null)
{
return NotFound();
}
order.Status = OrderStatus.Cancelled;
return Ok(order);
}
}
}
@@ -0,0 +1,102 @@
using EonaCat.DoxaApi.Attributes;
using Microsoft.AspNetCore.Mvc;
using SampleApi.Models;
namespace SampleApi.Controllers
{
[ApiController]
[Route("api/users")]
[DoxaApiGroup("Users")]
public class UsersController : ControllerBase
{
private static readonly List<User> _users = new()
{
new User { Id = Guid.NewGuid(), Name = "Ada Lovelace", Email = "ada@example.com", Role = UserRole.Admin, CreatedAt = DateTime.UtcNow },
new User { Id = Guid.NewGuid(), Name = "Alan Turing", Email = "alan@example.com", Role = UserRole.Member, CreatedAt = DateTime.UtcNow },
};
[HttpGet]
public ActionResult<List<User>> GetUsers([FromQuery] UserRole? role, [FromQuery] int page = 1)
{
var query = _users.AsEnumerable();
if (role is not null)
{
query = query.Where(u => u.Role == role);
}
return Ok(query.ToList());
}
[HttpGet("{id}")]
public ActionResult<User> GetById(Guid id)
{
var user = _users.FirstOrDefault(u => u.Id == id);
return user is null ? NotFound() : Ok(user);
}
[HttpPost]
[DoxaApiExample("""
{
"name": "Grace Hopper",
"email": "grace@example.com",
"role": "Member",
"address": { "street": "1 Compiler Way", "city": "Arlington", "postalCode": "22201", "country": "US" }
}
""")]
public ActionResult<User> Create([FromBody] CreateUserRequest request)
{
var user = new User
{
Id = Guid.NewGuid(),
Name = request.Name,
Email = request.Email,
Role = request.Role,
Address = request.Address,
CreatedAt = DateTime.UtcNow
};
_users.Add(user);
return CreatedAtAction(nameof(GetById), new { id = user.Id }, user);
}
[HttpPatch("{id}")]
public ActionResult<User> Update(Guid id, [FromBody] UpdateUserRequest request)
{
var user = _users.FirstOrDefault(u => u.Id == id);
if (user is null)
{
return NotFound();
}
if (request.Name is not null)
{
user.Name = request.Name;
}
if (request.Email is not null)
{
user.Email = request.Email;
}
if (request.Role is not null)
{
user.Role = request.Role.Value;
}
return Ok(user);
}
[HttpDelete("{id}")]
[Obsolete("Use POST /api/users/{id}/archive instead.")]
public IActionResult Delete(Guid id)
{
var user = _users.FirstOrDefault(u => u.Id == id);
if (user is null)
{
return NotFound();
}
_users.Remove(user);
return NoContent();
}
}
}
+86
View File
@@ -0,0 +1,86 @@
namespace SampleApi.Models
{
public enum UserRole
{
Admin,
Member,
Guest
}
public class User
{
public Guid Id { get; set; }
public string Name { get; set; } = "";
public string Email { get; set; } = "";
public UserRole Role { get; set; }
public DateTime CreatedAt { get; set; }
public Address? Address { get; set; }
public List<string> Tags { get; set; } = new();
}
public class Address
{
public string Street { get; set; } = "";
public string City { get; set; } = "";
public string PostalCode { get; set; } = "";
public string Country { get; set; } = "";
}
public class CreateUserRequest
{
public string Name { get; set; } = "";
public string Email { get; set; } = "";
public UserRole Role { get; set; } = UserRole.Member;
public Address? Address { get; set; }
}
public class UpdateUserRequest
{
public string? Name { get; set; }
public string? Email { get; set; }
public UserRole? Role { get; set; }
}
public class Order
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public List<OrderLine> Lines { get; set; } = new();
public decimal Total { get; set; }
public OrderStatus Status { get; set; }
public DateTime PlacedAt { get; set; }
}
public class OrderLine
{
public string Sku { get; set; } = "";
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
}
public enum OrderStatus
{
Pending,
Paid,
Shipped,
Delivered,
Cancelled
}
public class CreateOrderRequest
{
public Guid UserId { get; set; }
public List<OrderLine> Lines { get; set; } = new();
}
}
+27
View File
@@ -0,0 +1,27 @@
using EonaCat.DoxaApi;
using EonaCat.DoxaApi.Middleware;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddDoxaApi(options =>
{
options.Title = "Sample API";
options.Description = "A demo service showing off the DoxaApi UI - users and orders.";
options.Version = "v1";
options.AccentColor = "#6366f1";
});
var app = builder.Build();
app.UseRouting();
app.UseDoxaApi(options =>
{
options.RoutePrefix = "doxa";
});
app.MapControllers();
app.MapGet("/", () => Results.Redirect("/doxa"));
app.Run();
@@ -0,0 +1,12 @@
{
"profiles": {
"SampleApi": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:53010;http://localhost:53011"
}
}
}
+19
View File
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<!-- In your own app, replace this with a PackageReference to the published
DoxaApi NuGet package, e.g.:
<PackageReference Include="DoxaApi" Version="1.0.0" />
-->
<ProjectReference Include="..\..\DoxaApi\EonaCat.DoxaApi.csproj" />
</ItemGroup>
</Project>