Swagger/OpenAPI — Swashbuckle, XML comments, authentication UI

~20 daq · .NET Backend · API Sifati va Dizayn

Muammodan boshlaylik

Frontend jamoasi so'raydi: "Buyurtma yaratish uchun qanday maydonlar kerak? Qaysi biri majburiy? Xato bo'lsa nima qaytadi?". Siz Word faylida hujjat yozgansiz — u uch oy oldin yozilgan va endi kodga mos kelmaydi. Mobil jamoa esa API klientini qo'lda yozyapti va har bir o'zgarishda buziladi.


OpenAPI nima?

OpenAPI — HTTP API ni tavsiflash uchun standart (JSON/YAML): qanday endpoint lar bor, qanday parametrlar, qanday javoblar.

{
  "openapi": "3.1.1",
  "paths": {
    "/api/mahsulotlar/{id}": {
      "get": {
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } }],
        "responses": { "200": { "description": "OK" }, "404": { "description": "Not Found" } }
      }
    }
  }
}

Swagger — OpenAPI ning eski nomi va uni ko'rsatuvchi vositalar (Swagger UI).

Spetsifikatsiya koddan avtomatik yaratiladi — hujjat doim kodga mos.


Hayotiy o'xshatma

Restoran menyusi. Menyu oshxonaning o'zidan avtomatik chop etiladi: oshpaz yangi taom qo'shsa — u menyuda darhol paydo bo'ladi, taom olib tashlansa — menyudan ham yo'qoladi. Mehmon menyuga qarab nima buyurtma qilish mumkinligini, tarkibini va narxini biladi — oshxonaga kirmasdan.


.NET 9+ — o'rnatilgan OpenAPI

dotnet add package Microsoft.AspNetCore.OpenApi
builder.Services.AddOpenApi();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();             // GET /openapi/v1.json
}

.NET 9 dan boshlab shablonlarda Swashbuckle o'rniga Microsoft.AspNetCore.OpenApi ishlatiladi; u faqat spetsifikatsiyani yaratadi. Ko'rish uchun interfeys alohida qo'shiladi.

Scalar — zamonaviy interfeys

dotnet add package Scalar.AspNetCore
using Scalar.AspNetCore;

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
    app.MapScalarApiReference();      // /scalar/v1
}

Endpoint lar ro'yxati, sxemalar, "Try it" tugmasi va turli tillar uchun kod namunalari.

Swashbuckle — klassik Swagger UI

dotnet add package Swashbuckle.AspNetCore
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

app.UseSwagger();
app.UseSwaggerUI();                   // /swagger

Ko'plab mavjud loyihalarda ishlatiladi.


Hujjatni boyitish

Javob turlari

[HttpGet("{id:int}")]
[ProducesResponseType<MahsulotDto>(StatusCodes.Status200OK)]
[ProducesResponseType<ProblemDetails>(StatusCodes.Status404NotFound)]
public async Task<ActionResult<MahsulotDto>> Ol(int id, CancellationToken ct) { ... }

ActionResult<T> — 200 javob turi avtomatik aniqlanadi; boshqa kodlarni ProducesResponseType bilan qo'shing.

XML izohlar

<!-- .csproj -->
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
/// <summary>Mahsulotni ID bo'yicha qaytaradi.</summary>
/// <param name="id">Mahsulot identifikatori</param>
/// <response code="404">Mahsulot topilmadi</response>
[HttpGet("{id:int}")]
public async Task<ActionResult<MahsulotDto>> Ol(int id, CancellationToken ct) { ... }
public record MahsulotYaratDto(
    /// <summary>Mahsulot nomi, 2–100 belgi</summary>
    string Nomi,
    decimal Narx);

.NET 10 da o'rnatilgan OpenAPI XML izohlarni avtomatik o'qiydi; Swashbuckle da IncludeXmlComments bilan ulanadi.

Minimal API

app.MapGet("/api/mahsulotlar/{id:int}", Ol)
   .WithName("MahsulotOl")
   .WithSummary("Mahsulotni ID bo'yicha olish")
   .WithTags("Mahsulotlar")
   .Produces<MahsulotDto>()
   .ProducesProblem(StatusCodes.Status404NotFound);

JWT bilan sinash

Spetsifikatsiyaga Bearer sxemasini qo'shish (o'rnatilgan OpenAPI, document transformer):

builder.Services.AddOpenApi(o =>
{
    o.AddDocumentTransformer((doc, ctx, ct) =>
    {
        doc.Components ??= new();
        doc.Components.SecuritySchemes ??= new Dictionary<string, IOpenApiSecurityScheme>();
        doc.Components.SecuritySchemes["Bearer"] = new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.Http,
            Scheme = "bearer",
            BearerFormat = "JWT"
        };
        return Task.CompletedTask;
    });
});

Interfeysda "Authorize" — token kiritiladi va keyingi so'rovlarga qo'shiladi.

[!INFO] Microsoft.OpenApi kutubxonasining 2.x versiyasida (.NET 10) model turlari interfeyslarga o'tgan (IOpenApiSecurityScheme), .NET 9 da (1.x) esa Dictionary<string, OpenApiSecurityScheme>. Transformer kodini o'z versiyangizga moslang.


Spetsifikatsiyadan foydalanish

  • Klient generatsiyasi — NSwag, Kiota, openapi-typescript: TypeScript/C#/Kotlin klientlari avtomatik
  • Postman — openapi/v1.json ni import qilib kolleksiya yaratish va testlash
  • Contract testing — API spetsifikatsiyadan chetga chiqmaganini CI da tekshirish
  • Build vaqtida fayl yaratish — Microsoft.Extensions.ApiDescription.Server paketi bilan

[!WARNING] Production da hujjat ochiq bo'lishi kerakmi — ongli qaror qabul qiling. Ichki API uchun Swagger UI ni internetga ochish — hujumchiga barcha endpoint lar xaritasini berish. Odatda faqat IsDevelopment() da yoki autentifikatsiya ortida.


Tez-tez uchraydigan xatolar

IActionResult qaytarish va ProducesResponseType siz — hujjatda javob sxemasi bo'sh.

XML hujjat fayli yoqilmagan — izohlar ko'rinmaydi.

Bir xil nomdagi DTO lar turli namespace larda — sxema nomlari to'qnashadi.


Xulosa

OpenAPI — API ning standart mashina o'qiy oladigan tavsifi, koddan avtomatik yaratiladi — hujjat doim dolzarb. .NET 9+: AddOpenApi + MapOpenApi (/openapi/v1.json), interfeys — Scalar (MapScalarApiReference) yoki Swashbuckle (Swagger UI).

Boyitish: ActionResult<T>, ProducesResponseType, XML izohlar, Minimal API da WithSummary/Produces. Bearer sxemasi — document transformer. Spetsifikatsiyadan klient generatsiyasi, Postman import, contract testing. Production da ochiqligini ongli hal qiling.


Keyingi dars

73-dars: API Versioning — v1, v2, URL va header versiyalash