14. Minimal APIs and controllers
Sections
Reading settings
Natural voice recorded for this course, the same in every browser.
No voice for this language in this browser.
More voices
Code and English terms
Off: the page’s voice reads everything, with no pause between two voices.
No voice for this language in this browser.
More voices
More voices: Microsoft Edge has natural online voices, and Windows (Settings › Time & language › Speech), macOS and Android install others.
Minimal APIs and controllers both publish endpoints through ASP.NET Core endpoint routing. Choose by composition needs, not by slogans.
Binding is part of the public contract
Section titled “Binding is part of the public contract”A route handler can bind route values, query strings, headers, services and bodies directly from parameters. Make the source explicit when ambiguity would be dangerous. The lesson binds root from the route and notes from the query, then applies an endpoint filter:
without key: 400; with key: 200 {"root":"C","notes":7}TypedResults preserve concrete response types for tests and OpenAPI metadata. An endpoint filter can validate or decorate a route-handler family, but authorization should use the framework authorization system and endpoint metadata rather than an improvised header filter.
Where controllers remain deep
Section titled “Where controllers remain deep”Controllers provide conventions for action discovery, model binding, filters, validation responses and larger APIs. The lesson maps a controller and a Minimal API into the same routing table:
controller: 200 {"symbol":"Cmaj7","characters":5}Do not duplicate one use case in both styles. Keep transport binding thin and call the same application seam.
Streaming
Section titled “Streaming”Returning IAsyncEnumerable<T> lets JSON serialization consume items asynchronously. The lesson emits three chords as one JSON array. This avoids buffering the whole source in application code, but proxies and formatters may still buffer. For progressive delivery, measure the full path and choose an explicit framing protocol such as NDJSON, SSE or SignalR when appropriate.
Run the proof
Section titled “Run the proof”dotnet run --project code/csharp-advanced/Advanced -c Release -- l14The checked transcript is expected/l14.txt.
Exercises
Section titled “Exercises”- Add a negative
notesvalue. Define one portable error body and test status, media type and payload. - Implement the same application operation behind one Minimal API and one controller adapter without duplicating policy.
- Cancel the streamed request after the first item and prove the source observes cancellation.
Solutions
- Reject at the transport boundary with a stable problem-details contract. Validation success is not authorization success.
- Bind transport inputs into one command/query type, call one application handler, and map its result independently in each adapter.
- Pass
RequestAbortedinto the async iterator, dispose the response early in the client, and assert the iterator’sfinallyor cancellation probe ran.