4. Adding a REST API¶
You have commands and queries, but no way to reach them over HTTP. The [RestApi] attribute fixes that — handlers you've already decorated with [HttpGet] and [HttpPost] become Minimal API endpoints with generated routing, validation, and OpenAPI docs.
Declare the API¶
[RestApi(RoutePrefix = "/api/catalog", Title = "Library Catalog API")]
public partial class CatalogRestApi;
The generator scans handlers with HTTP attributes and produces:
AddCatalogRestApi()— DI registration (JSON options, CORS, OpenAPI)MapCatalogRestApi()— maps every[HttpGet]/[HttpPost]handler as a Minimal API route
You already decorated your handlers in Chapter 3:
[HttpPost("/books")] // → POST /api/catalog/books
[HttpGet("/books/search")] // → GET /api/catalog/books/search
These attributes don't do anything on their own — they're metadata. The [RestApi] generator reads them and produces the endpoint wiring.
Rate Limiting¶
AddBook already has [RateLimit("default")]. This generates rate-limiting middleware on the endpoint. One attribute, instant protection. The policy name ("default") references a rate-limiting policy you configure in your host — but even before that, the attribute documents intent.
What Gets Generated¶
The generated REST API code lives in generated/Deepstaging.Web.WebEndpointGenerator/. You'll find:
- Route registration (
app.MapPost("/api/catalog/books", ...)) - Request deserialization and validation (from the
[Required]/[MaxLength]attributes on your command records) - Response serialization
- OpenAPI metadata
Run It¶
You'll need a host to actually serve HTTP — that comes later when you compose your contexts. For now, the generated code compiles and the endpoints are ready to wire.
No errors? The API surface is defined. You'll see it in action when we compose the full application.