Tài liệu ASP.NET Core Web API với Swagger / OpenAPI
Bởi Rico Suter
Bài viết này đề cập đến việc sử dụng công cụ Swagger — được cung cấp bởi các package Swashbuckle.AspNetCore và NSwag — để tạo tài liệu OpenAPI và các trang trợ giúp tương tác cho ASP.NET Core web API.
Trong .NET 9 trở lên, ASP.NET Core đã tích hợp hỗ trợ OpenAPI (OpenAPI support) sẵn có thay thế Swashbuckle làm mặc định. Swashbuckle không còn được đưa vào các template dự án, nhưng vẫn có thể sử dụng dưới dạng community package thêm vào thủ công.
- Để hiểu về các tính năng OpenAPI tích hợp sẵn, xem Tổng quan hỗ trợ OpenAPI trong ứng dụng ASP.NET Core API.
- Để thêm Swagger UI cho mục đích khám phá tương tác hoặc kiểm thử cục bộ bên cạnh hỗ trợ OpenAPI tích hợp, xem Sử dụng tài liệu OpenAPI đã tạo.
Các hướng dẫn sau đây áp dụng cho các dự án sử dụng Swashbuckle hoặc NSwag với ASP.NET Core 8.0 và phiên bản cũ hơn.
Swagger (OpenAPI) là một đặc tả (specification) không phụ thuộc ngôn ngữ để mô tả REST API. Nó cho phép cả máy tính lẫn con người hiểu được khả năng của REST API mà không cần truy cập trực tiếp vào mã nguồn. Các mục tiêu chính của nó là:
- Giảm thiểu lượng công việc cần thiết để kết nối các dịch vụ tách rời (decoupled services).
- Giảm thời gian cần thiết để tài liệu hóa chính xác một dịch vụ.
Hai triển khai OpenAPI chính cho .NET là Swashbuckle và NSwag, xem:
OpenAPI và Swagger
Dự án Swagger đã được đóng góp cho OpenAPI Initiative vào năm 2015 và từ đó được gọi là OpenAPI. Cả hai tên đều được dùng thay thế nhau. Tuy nhiên, "OpenAPI" đề cập đến đặc tả. "Swagger" đề cập đến nhóm các sản phẩm mã nguồn mở và thương mại từ SmartBear hoạt động với OpenAPI Specification. Các sản phẩm mã nguồn mở tiếp theo, như OpenAPIGenerator, cũng thuộc nhóm Swagger, dù không được phát hành bởi SmartBear.
Tóm lại:
- OpenAPI là một đặc tả.
- Swagger là công cụ sử dụng đặc tả OpenAPI. Ví dụ: OpenAPIGenerator và SwaggerUI.
Đặc tả OpenAPI (openapi.json)
Đặc tả OpenAPI là một tài liệu mô tả khả năng của API của bạn. Tài liệu dựa trên các annotation XML và attribute trong các controller và model. Đây là phần cốt lõi của quy trình OpenAPI và được dùng để điều khiển các công cụ như SwaggerUI. Theo mặc định, nó được đặt tên là openapi.json. Đây là ví dụ về đặc tả OpenAPI, được rút gọn để ngắn gọn:
{
"openapi": "3.0.1",
"info": {
"title": "API V1",
"version": "v1"
},
"paths": {
"/api/Todo": {
"get": {
"tags": [
"Todo"
],
"operationId": "ApiTodoGet",
"responses": {
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ToDoItem"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ToDoItem"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ToDoItem"
}
}
}
}
}
}
},
"post": {
…
}
},
"/api/Todo/{id}": {
"get": {
…
},
"put": {
…
},
"delete": {
…
}
}
},
"components": {
"schemas": {
"ToDoItem": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"name": {
"type": "string",
"nullable": true
},
"isCompleted": {
"type": "boolean"
}
},
"additionalProperties": false
}
}
}
}Swagger UI
Swagger UI cung cấp giao diện người dùng (UI) dựa trên web hiển thị thông tin về dịch vụ, sử dụng đặc tả OpenAPI đã tạo. Cả Swashbuckle và NSwag đều bao gồm phiên bản nhúng (embedded version) của Swagger UI, để nó có thể được lưu trữ trong ứng dụng ASP.NET Core của bạn bằng lời gọi đăng ký middleware (middleware registration call).
Mỗi phương thức action (action method) công khai trong các controller của bạn có thể được kiểm thử từ UI. Chọn tên phương thức để mở rộng phần. Thêm các tham số cần thiết và chọn Try it out!.
Lưu ý: Phiên bản Swagger UI được dùng cho ảnh chụp màn hình là phiên bản 2. Để xem ví dụ phiên bản 3, xem Petstore example.
Bảo mật các endpoint Swagger UI
Gọi MapSwagger().RequireAuthorization để bảo mật các endpoint Swagger UI. Ví dụ sau bảo mật các endpoint swagger:
using System.Security.Claims;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddAuthorization();
builder.Services.AddAuthentication("Bearer").AddJwtBearer();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapSwagger().RequireAuthorization();
app.MapGet("/", () => "Hello, World!");
app.MapGet("/secret", (ClaimsPrincipal user) => $"Hello {user.Identity?.Name}. My secret")
.RequireAuthorization();
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.WithOpenApi();
app.Run();
internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}Trong đoạn code trên, endpoint /weatherforecast không cần xác thực, nhưng các endpoint Swagger thì có.
Curl sau đây truyền JWT token để kiểm thử endpoint Swagger UI:
curl -i -H "Authorization: Bearer {TOKEN}" https://localhost:{PORT}/swagger/v1/swagger.jsonTrong đó {TOKEN} là JWT bearer token và {PORT} là số cổng.
Để biết thêm thông tin về kiểm thử với JWT token, xem Tạo token với dotnet user-jwts.
Tạo file tài liệu XML tại thời điểm biên dịch
Xem GenerateDocumentationFile để biết thêm thông tin.