# 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<string>()
        }
    });

    // 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<AlertThreshold>), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status409Conflict)]
    public async Task<IActionResult> 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
/// <summary>
/// Creates a new alert threshold for an observation code.
/// </summary>
/// <param name="req">Threshold bounds and display metadata.</param>
/// <returns>The created threshold.</returns>
[HttpPost]
public async Task<IActionResult> Create([FromBody] AlertThresholdRequest req)
```

The `<summary>` appears as the endpoint description in Swagger UI. The `<param>` tags describe individual parameters. The `<returns>` tag describes the response.

**How does this work?** When you build a C# project with `<GenerateDocumentationFile>true</GenerateDocumentationFile>` 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 `<summary>` XML comment
   - Parameter descriptions from `<param>` 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 <token>` 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 `<summary>` 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)
