# Guide 20: OpenAPI / Swagger Documentation ## What is OpenAPI and Swagger? **OpenAPI** (formerly called Swagger Specification) is a standard format for describing REST APIs. An OpenAPI specification is a JSON or YAML file that lists every endpoint, its parameters, request/response shapes, authentication requirements, and error codes. Think of it as a machine-readable instruction manual for your API. **Swagger** is a set of tools that work with OpenAPI specifications: - **Swagger UI**: A web-based interactive API explorer. Developers can browse endpoints, see parameter descriptions, and make live test requests — all from the browser, without writing any code. - **Swashbuckle**: A .NET library that automatically generates the OpenAPI specification from your controller code and XML documentation comments, and hosts Swagger UI. **Why does this matter?** Without API documentation, frontend developers need to read the backend C# code (or ask the backend developer) to understand how to call each endpoint. With Swagger UI, they open a browser, see every endpoint, and can test them immediately. The documentation stays in sync with the code automatically because it's generated from the code. --- ## Setup in Program.cs ```csharp builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(options => { // Basic API information options.SwaggerDoc("v1", new OpenApiInfo { Title = "VigilCare Clinical API", Version = "v1", Description = "Clinical monitoring and alerting platform API" }); // Tell Swagger UI that the API requires a JWT Bearer token options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Name = "Authorization", Type = SecuritySchemeType.Http, Scheme = "bearer", BearerFormat = "JWT", In = ParameterLocation.Header, Description = "Enter your JWT token" }); // Apply the Bearer requirement to all endpoints by default options.AddSecurityRequirement(document => new OpenApiSecurityRequirement { { new OpenApiSecuritySchemeReference("Bearer", document), new List() } }); // Include XML documentation comments from the compiled assembly var xmlPath = Path.Combine(AppContext.BaseDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"); options.IncludeXmlComments(xmlPath); }); ``` **What does each part do?** | Setting | Purpose | |---------|---------| | `AddEndpointsApiExplorer()` | Enables the metadata extraction that Swashbuckle needs to discover your endpoints | | `SwaggerDoc("v1", ...)` | Names the API spec "v1" with a title and description shown at the top of Swagger UI | | `AddSecurityDefinition("Bearer", ...)` | Adds an "Authorize" button to Swagger UI where developers can paste their JWT token | | `AddSecurityRequirement(...)` | Shows a lock icon on every endpoint, indicating authentication is required | | `IncludeXmlComments(xmlPath)` | Reads the `///` XML doc comments from your C# code and displays them as endpoint descriptions | ### Enabling Swagger UI ```csharp app.UseSwagger(); // Serves the OpenAPI spec at /swagger/v1/swagger.json app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "VigilCare Clinical API v1"); }); ``` Available at: `http://localhost:5270/swagger/ui` --- ## Writing Good Swagger Documentation Swagger UI shows two things about each endpoint: information from your C# code attributes, and information from XML documentation comments. ### Controller and Action Attributes ```csharp [ApiController] [Route("api/v1/alert-thresholds")] [Produces("application/json")] [Authorize] public class AlertThresholdsController : ControllerBase { [HttpPost] [AuthorizePermission(ClinicalPermissions.ThresholdsWrite)] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status201Created)] [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status409Conflict)] public async Task Create([FromBody] AlertThresholdRequest req) ``` - **`[Produces("application/json")]`** tells Swagger the response format - **`[ProducesResponseType(...)]`** documents which status codes the endpoint can return and what the response body looks like. Swagger UI shows these as expandable response examples. - **`[FromBody]`** tells Swagger the request body schema comes from `AlertThresholdRequest` ### XML Documentation Comments ```csharp /// /// Creates a new alert threshold for an observation code. /// /// Threshold bounds and display metadata. /// The created threshold. [HttpPost] public async Task Create([FromBody] AlertThresholdRequest req) ``` The `` appears as the endpoint description in Swagger UI. The `` tags describe individual parameters. The `` tag describes the response. **How does this work?** When you build a C# project with `true` in the `.csproj` file, the compiler creates an XML file containing all `///` comments. Swashbuckle reads this XML file at runtime and merges the comments into the OpenAPI specification. --- ## What Swagger UI Shows When you open `http://localhost:5270/swagger/ui`, you see: 1. **API title and description** from `SwaggerDoc()` 2. **Grouped endpoints** organized by controller (Encounters, Observations, Alert Thresholds, FHIR, etc.) 3. **For each endpoint**: - HTTP method and URL (e.g., `POST /api/v1/encounters/{encounterId}/observations`) - Summary from `` XML comment - Parameter descriptions from `` XML comments - Request body schema (auto-generated from the C# request class) - Response schemas for each status code (from `[ProducesResponseType]`) 4. **"Authorize" button** — paste a JWT token to authenticate all subsequent requests 5. **"Try it out" button** — fill in parameters and execute real requests against the running API --- ## Security Scheme in Swagger UI The security definition adds an "Authorize" button at the top of Swagger UI: ```csharp options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Name = "Authorization", Type = SecuritySchemeType.Http, Scheme = "bearer", BearerFormat = "JWT", In = ParameterLocation.Header, Description = "Enter your JWT token" }); ``` **How to use it:** 1. Call `POST /api/v1/auth/login` with username/password to get a token 2. Click "Authorize" in Swagger UI 3. Paste the token (without the "Bearer " prefix — Swagger adds it automatically) 4. Click "Authorize" — all subsequent requests include the `Authorization: Bearer ` header --- ## The Generated OpenAPI Specification The raw specification is available at `/swagger/v1/swagger.json`. It's a standard OpenAPI 3.0 document that can be consumed by: - **Code generators**: Generate API client libraries for TypeScript, Python, Java, etc. using tools like `openapi-generator` or `nswag` - **Testing tools**: Import into Postman, Insomnia, or Bruno for manual testing - **Documentation platforms**: Host on ReadMe, Stoplight, or Redocly for public documentation - **Contract testing**: Validate that the API implementation matches the specification --- ## Key Takeaways - **Swagger UI makes your API self-documenting** — developers can explore and test endpoints from a browser without reading C# code - **Write `` comments on every controller action** — they become the endpoint descriptions in Swagger UI. Without them, endpoints are listed without any explanation. - **Use `[ProducesResponseType]` for every status code** — this documents the possible responses and their shapes, making it clear what success and error responses look like - **The security definition enables authenticated testing** — developers can paste a JWT token in the UI and test protected endpoints without using curl or Postman - **The OpenAPI spec is a machine-readable contract** — frontend teams can generate TypeScript API clients from it, ensuring type-safe API calls without manual typing - **Documentation stays in sync with code** — because it's generated from the actual controller code and attributes, it can never go stale (unlike a manually-written Wiki page)