feature: MIMIC-IV Replay Scenario Generator
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user