In this lab you'll evolve a small TechConf Minimal API from a single unversioned contract into a properly versioned .NET 10 API using Asp.Versioning and the built-in OpenAPI stack.
The starter already exposes a flat event response for existing consumers. Your job is to introduce URL-path versioning, keep the existing V1 shape for backward compatibility, add a richer V2 contract, deprecate V1, and generate one OpenAPI document per version with Scalar as the UI.
- Configure API versioning for Minimal APIs with
Asp.Versioning - Use URL segment versioning with
/api/v{version}/... - Serve two API contracts side-by-side without breaking old clients
- Mark an older version as deprecated and report supported versions in response headers
- Generate separate OpenAPI documents for each version and expose them through Scalar
The TechConf API started with a simple event contract:
{ "id": 1, "title": "TechConf 2026", "startDate": "2026-09-15T09:00:00", "location": "Main Hall, Munich" }That worked for early consumers, but newer clients now need more detail:
- event description
- end date
- structured venue information
- registration counts
- publishing status
You cannot break the existing clients, so you need to keep V1 alive while introducing V2.
cd labs/lab-api-versioning/exercise/TechConf.Api
dotnet runOpen https://localhost:5001/scalar/v1 to inspect the API docs while you work.
Open Program.cs and replace the simple OpenAPI setup with the version-aware configuration:
- add
AddApiVersioning(...) - use
UrlSegmentApiVersionReader - enable
ReportApiVersions - add the versioned API explorer with
GroupNameFormat = "'v'VVV" - enable URL substitution for route templates
- register the version-aware
AddOpenApi()
The required NuGet packages are already referenced in the project so you can focus on the implementation.
Open Endpoints/EventEndpoints.cs and convert the current unversioned /api/events endpoints into:
GET /api/v1/eventsGET /api/v1/events/{id}
Keep the current flat V1 response shape so existing consumers can migrate with minimal surprises.
Still in EventEndpoints.cs, expose a richer V2 contract:
GET /api/v2/eventsGET /api/v2/events/{id}
Use the provided V2 DTOs so the new contract returns:
descriptionendDate- nested
venue registeredCountstatus
Mark API version 1.0 as deprecated while keeping it available.
Verify that V1 responses include version-reporting headers such as:
api-supported-versionsapi-deprecated-versions
Update the development-only OpenAPI/Scalar setup in Program.cs so that:
/openapi/v1.jsononly contains V1 endpoints/openapi/v2.jsononly contains V2 endpoints- Scalar shows both documents in its version switcher
Use requests.http to verify:
- V1 returns the flat
locationstring - V2 returns the structured
venueobject - V1 is reported as deprecated
- both OpenAPI documents are available separately
- Add a version-neutral endpoint such as
/health - Add a Sunset policy for V1 so clients know when it will be retired
- Support both URL segment and header versioning at the same time
A complete reference solution is available in the solution/ directory.