C# Advanced Capstone: Ship a Production API
Design, implement, secure, test, observe, and package a production-style ASP.NET Core order API using the advanced course’s language and architecture skills.
Before this lesson
Deliver a layered production-style API
Prove reliability and security through tests
Package observable reproducible deployment
The short answer
Build the capstone as vertical slices over explicit domain rules: create and query orders, persist transactionally, call one resilient dependency, authorize resource access, test through HTTP, emit telemetry, and package one reproducible deployment artifact.
Build the runtime mental model
The capstone is an order API with create, retrieve, list, cancel, and summary operations. The domain protects valid order state; application handlers coordinate transactions; adapters own EF Core, HTTP, time, identity, and telemetry.
Advanced C# work improves when you separate language syntax, runtime behavior, and application policy. Write down which layer owns the guarantee in this lesson. Then identify the observable evidence—a compiler rejection, test result, generated query, trace, or measurement—that would prove the model correct.
Design the boundary deliberately
Implement one vertical slice at a time. Define the HTTP contract and acceptance examples, write the domain rule, persist it, expose the endpoint, and add unit plus integration coverage before starting the next slice. Maintain a schema migration and seed only non-sensitive demonstration data.
The starter isolates one part of the mental model so it can run in the browser. The exercise moves the same rule into a current local .NET project where packages, framework hosting, diagnostics, and multi-file tests are available.
using System;
using System.Collections.Generic;
class Order
{
public string Id { get; private set; }
public bool Cancelled { get; private set; }
public Order(string id) { if (string.IsNullOrWhiteSpace(id)) throw new ArgumentException("id"); Id = id; }
public void Cancel() { if (Cancelled) throw new InvalidOperationException("Already cancelled."); Cancelled = true; }
}
class Program
{
static void Main()
{
var order = new Order("ORD-1001");
order.Cancel();
Console.WriteLine(order.Id + ":" + order.Cancelled);
}
}Expected output
ORD-1001:True
Diagnose failure and misuse
Reject duplicate idempotency keys, unauthorized cross-user access, invalid transitions, malformed payloads, missing records, optimistic concurrency conflicts, dependency timeouts, and shutdown cancellation. No handler may swallow an exception or return secret diagnostics.
Classify each failure as a contract violation, transient operational failure, permanent dependency response, concurrency conflict, or programmer defect. That classification determines whether to reject, retry, compensate, cancel, or fail fast. A generic catch-and-continue policy destroys the information needed to make that decision.
| Question | Evidence to inspect | Decision |
|---|---|---|
| Is the input valid? | Validation result and boundary examples | Reject with a stable contract |
| Is the failure transient? | Typed status, exception, and policy context | Retry only when bounded and safe |
| Is state still consistent? | Invariant and transaction outcome | Commit, compensate, or abort |
| Is performance acceptable? | Representative latency and allocation data | Keep simple or optimize one cause |
Apply the concept in production
Publish a container and documented local stack, validate configuration at startup, run migrations through a controlled step, expose separate liveness and readiness probes, and create a dashboard or query set for request rate, errors, latency, dependency failures, and queue or database pressure.
Finish by making the result operable. Add structured diagnostics at the boundary, propagate cancellation, avoid sensitive data, and record SDK and dependency versions. Test the public behavior instead of private implementation details. If a framework or provider performs translation, serialization, concurrency, or I/O, include at least one test against the real production technology.
A senior-level review should be able to answer four questions: what contract is promised, who owns lifetime and cleanup, how failures become visible, and what evidence supports the design. If any answer depends on “the framework probably handles it,” inspect the documentation or runtime behavior and turn the assumption into a checked decision.
Quick knowledge check
Answer before you reveal.
01What makes this capstone production-style rather than merely large?
It proves explicit contracts, failure handling, security, persistence, integration behavior, observability, and reproducible deployment—not just feature count.
02What must happen before adding complexity to this design?
State the requirement, preserve a correct baseline, collect evidence, and explain how the proposed mechanism improves a specific quality.
Exercise
Practice challenge
Ship the complete order API with documented contracts, EF Core persistence, resilient outbound pricing, authorization, integration tests, telemetry, health probes, and container instructions.
Requirements
- The implementation states its contract and ownership boundary explicitly
- Automated checks cover the successful path and at least two meaningful failures
- Diagnostics expose failure context without secrets or swallowed exceptions
- The project documents required SDK, packages, setup, run, and test commands
Optional extension: Measure or load-test the critical path and record whether the evidence justifies another optimization or abstraction.
Open in C# compilerLesson checkpoint
One small step locks it in
Mark this lesson complete, then keep the momentum going.
Clear up the details
Frequently asked questions
When should I use advanced capstone: ship a production api?
Use it when its explicit tradeoff solves a measured requirement or clarifies an owned boundary. Keep the simpler design when the additional mechanism does not improve correctness, operability, or changeability.
Does the browser compiler cover the complete production setup?
No. It runs the focused starter program. Framework, package, database, benchmark, and multi-project work requires a current local .NET SDK and the project commands described in the exercise.
What evidence should I keep after the exercise?
Keep the acceptance cases, automated tests, diagnostic or benchmark output where relevant, and a short decision note describing the chosen boundary and rejected alternative.