Bagikan melalui


Mulai menggunakan Microsoft.AspNetCore.OpenApi

Paket ini Microsoft.AspNetCore.OpenApi menyediakan dukungan bawaan untuk pembuatan dokumen OpenAPI di ASP.NET Core. Paket:

  • Kompatibel dengan AoT asli.
  • Memanfaatkan JSdukungan skema ON yang disediakan oleh System.Text.Json.
  • Menyediakan API transformator untuk memodifikasi dokumen yang dihasilkan.
  • Mendukung pengelolaan beberapa dokumen OpenAPI dalam satu aplikasi.

Penginstalan paket

Pasang paket Microsoft.AspNetCore.OpenApi:

Jalankan perintah berikut dari Konsol Manajer Paket:

Install-Package Microsoft.AspNetCore.OpenApi -IncludePrerelease

Mengonfigurasi pembuatan dokumen OpenAPI

Kode berikut:

  • Menambahkan layanan OpenAPI.
  • Mengaktifkan titik akhir untuk menampilkan dokumen OpenAPI dalam JSformat ON.
var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi();

app.MapGet("/", () => "Hello world!");

app.Run();

Luncurkan aplikasi dan navigasi ke https://localhost:<port>/openapi/v1.json untuk melihat dokumen OpenAPI yang dihasilkan.

Pentingnya nama dokumen

Setiap dokumen OpenAPI dalam aplikasi memiliki nama yang unik. Nama dokumen default yang terdaftar adalah v1.

builder.Services.AddOpenApi(); // Document name is v1

Nama dokumen dapat dimodifikasi dengan meneruskan nama sebagai parameter ke AddOpenApi panggilan.

builder.Services.AddOpenApi("internal"); // Document name is internal

Nama dokumen muncul di beberapa tempat dalam implementasi OpenAPI.

Saat mengambil dokumen OpenAPI yang dihasilkan, nama dokumen disediakan sebagai documentName argumen parameter dalam permintaan. Permintaan berikut menyelesaikan v1 dokumen dan internal .

GET http://localhost:5000/openapi/v1.json
GET http://localhost:5000/openapi/internal.json

Opsi untuk Menyesuaikan pembuatan dokumen OpenAPI

Bagian berikut menunjukkan cara menyesuaikan pembuatan dokumen OpenAPI.

Mengkustomisasi versi OpenAPI dari dokumen yang dihasilkan

Secara default, pembuatan dokumen OpenAPI membuat dokumen yang sesuai dengan v3.0 dari spesifikasi OpenAPI. Kode berikut menunjukkan cara mengubah versi default dokumen OpenAPI:

builder.Services.AddOpenApi(options =>
{
    options.OpenApiVersion = OpenApiSpecVersion.OpenApi2_0;
});

Mengkustomisasi rute titik akhir OpenAPI

Secara default, titik akhir OpenAPI terdaftar melalui panggilan untuk MapOpenApi mengekspos dokumen di /openapi/{documentName}.json titik akhir. Kode berikut menunjukkan cara mengkustomisasi rute tempat dokumen OpenAPI terdaftar:

app.MapOpenApi("/openapi/{documentName}/openapi.json");

Catatan: Dimungkinkan, tetapi tidak disarankan, untuk menghapus documentName parameter rute dari rute titik akhir. documentName Saat parameter rute dihapus dari rute titik akhir, kerangka kerja mencoba menyelesaikan nama dokumen dari parameter kueri. Tidak menyediakan documentName dalam rute atau kueri dapat mengakibatkan perilaku yang tidak terduga.

Mengkustomisasi titik akhir OpenAPI

Karena dokumen OpenAPI disajikan melalui titik akhir handler rute, kustomisasi apa pun yang tersedia untuk titik akhir minimal standar tersedia untuk titik akhir OpenAPI.

Menyesuaikan titik akhir OpenAPI dengan metadata titik akhir

Daftar berikut ini memperlihatkan metadata titik akhir yang digunakan untuk mengkustomisasi dokumen OpenAPI yang dihasilkan:

Untuk mempelajari selengkapnya tentang menyesuaikan dokumen OpenAPI yang dihasilkan dengan memodifikasi metadata titik akhir, lihat Cara menggunakan OpenAPI di aplikasi API Minimal.

Membatasi akses dokumen OpenAPI ke pengguna yang berwenang

Titik akhir OpenAPI tidak mengaktifkan pemeriksaan otorisasi secara default. Namun, dimungkinkan untuk membatasi akses ke dokumen OpenAPI. Misalnya, dalam kode berikut, akses ke dokumen OpenAPI terbatas pada yang memiliki tester peran:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder();

builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization(o =>
{
    o.AddPolicy("ApiTesterPolicy", b => b.RequireRole("tester"));
});
builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi()
    .RequireAuthorization("ApiTesterPolicy");

app.MapGet("/", () => "Hello world!");

app.Run();

Dokumen OpenAPI yang dihasilkan cache

Dokumen OpenAPI diregenerasi setiap kali permintaan ke titik akhir OpenAPI dikirim. Regenerasi memungkinkan transformator untuk menggabungkan status aplikasi dinamis ke dalam operasi mereka. Misalnya, meregenerasi permintaan dengan detail konteks HTTP. Jika berlaku, dokumen OpenAPI dapat di-cache untuk menghindari eksekusi alur pembuatan dokumen pada setiap permintaan HTTP.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder();

builder.Services.AddOutputCache(options =>
{
    options.AddBasePolicy(policy => policy.Expire(TimeSpan.FromMinutes(10)));
});
builder.Services.AddOpenApi();

var app = builder.Build();

app.UseOutputCache();

app.MapOpenApi()
    .CacheOutput();

app.MapGet("/", () => "Hello world!");

app.Run();

Transformator dokumen OpenAPI

Bagian ini menunjukkan cara menyesuaikan dokumen OpenAPI dengan transformator.

Menyesuaikan dokumen OpenAPI dengan transformator

Transformer menyediakan API untuk memodifikasi dokumen OpenAPI dengan kustomisasi yang ditentukan pengguna. Transformer berguna untuk skenario seperti:

  • Menambahkan parameter ke semua operasi dalam dokumen.
  • Memodifikasi deskripsi untuk parameter atau operasi.
  • Menambahkan informasi tingkat atas ke dokumen OpenAPI.

Transformer termasuk dalam dua kategori:

  • Transformator dokumen memiliki akses ke seluruh dokumen OpenAPI. Ini dapat digunakan untuk membuat modifikasi global pada dokumen.
  • Transformator operasi berlaku untuk setiap operasi individu. Setiap operasi individu adalah kombinasi jalur dan metode HTTP. Ini dapat digunakan untuk mengubah parameter atau respons pada titik akhir.

Transformer dapat didaftarkan ke dokumen melalui UseTransformer panggilan pada OpenApiOptions objek. Cuplikan berikut menunjukkan berbagai cara untuk mendaftarkan transformator ke dokumen:

  • Daftarkan transformator dokumen menggunakan delegasi.
  • Daftarkan transformator dokumen menggunakan instans IOpenApiDocumentTransformer.
  • Daftarkan transformator dokumen menggunakan yang diaktifkan IOpenApiDocumentTransformerDI .
  • Daftarkan transformator operasi menggunakan delegasi.
using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi(options =>
{
    options.UseTransformer((document, context, cancellationToken) 
                             => Task.CompletedTask);
    options.UseTransformer(new MyDocumentTransformer());
    options.UseTransformer<MyDocumentTransformer>();
    options.UseOperationTransformer((operation, context, cancellationToken)
                            => Task.CompletedTask);
});

var app = builder.Build();

app.MapOpenApi();

app.MapGet("/", () => "Hello world!");

app.Run();

Urutan eksekusi untuk transformator

Transformer dijalankan dalam urutan first-in first-out berdasarkan pendaftaran. Dalam cuplikan berikut, transformator dokumen memiliki akses ke modifikasi yang dibuat oleh transformator operasi:

var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi(options =>
{
    options.UseOperationTransformer((operation, context, cancellationToken)
                                     => Task.CompletedTask);
    options.UseTransformer((document, context, cancellationToken)
                                     => Task.CompletedTask);
});

var app = builder.Build();

app.MapOpenApi();

app.MapGet("/", () => "Hello world!");

app.Run();

Menggunakan transformator dokumen

Transformator dokumen memiliki akses ke objek konteks yang mencakup:

  • Nama dokumen yang sedang dimodifikasi.
  • Daftar yang ApiDescriptionGroups terkait dengan dokumen tersebut.
  • yang IServiceProvider digunakan dalam pembuatan dokumen.

Transformator dokumen juga dapat mengubah dokumen OpenAPI yang dihasilkan. Contoh berikut menunjukkan transformator dokumen yang menambahkan beberapa informasi tentang API ke dokumen OpenAPI.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;

var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi(options =>
{
    options.UseTransformer((document, context, cancellationToken) =>
    {
        document.Info = new()
        {
            Title = "Checkout API",
            Version = "v1",
            Description = "API for processing checkouts from cart."
        };
        return Task.CompletedTask;
    });
});

var app = builder.Build();

app.MapOpenApi();

app.MapGet("/", () => "Hello world!");

app.Run();

Transformer dokumen yang diaktifkan layanan dapat menggunakan instans dari DI untuk memodifikasi aplikasi. Sampel berikut menunjukkan transformator dokumen yang menggunakan IAuthenticationSchemeProvider layanan dari lapisan autentikasi. Ini memeriksa apakah ada skema terkait pembawa JWT yang terdaftar di aplikasi dan menambahkannya ke tingkat atas dokumen OpenAPI:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder();

builder.Services.AddAuthentication().AddJwtBearer();

builder.Services.AddOpenApi(options =>
{
    options.UseTransformer<BearerSecuritySchemeTransformer>();
});

var app = builder.Build();

app.MapOpenApi();

app.MapGet("/", () => "Hello world!");

app.Run();

internal sealed class BearerSecuritySchemeTransformer(IAuthenticationSchemeProvider authenticationSchemeProvider) : IOpenApiDocumentTransformer
{
    public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
    {
        var authenticationSchemes = await authenticationSchemeProvider.GetAllSchemesAsync();
        if (authenticationSchemes.Any(authScheme => authScheme.Name == "Bearer"))
        {
            var requirements = new Dictionary<string, OpenApiSecurityScheme>
            {
                ["Bearer"] = new OpenApiSecurityScheme
                {
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer", // "bearer" refers to the header name here
                    In = ParameterLocation.Header,
                    BearerFormat = "Json Web Token"
                }
            };
            document.Components ??= new OpenApiComponents();
            document.Components.SecuritySchemes = requirements;
        }
    }
}

Transformator dokumen unik untuk instans dokumen yang terkait dengannya. Dalam contoh berikut, transformator:

  • Mendaftarkan persyaratan terkait autentikasi ke internal dokumen.
  • Membiarkan dokumen tidak dimodifikasi public .
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder();

builder.Services.AddAuthentication().AddJwtBearer();

builder.Services.AddOpenApi("internal", options =>
{
    options.UseTransformer<BearerSecuritySchemeTransformer>();
});
builder.Services.AddOpenApi("public");

var app = builder.Build();

app.MapOpenApi();

app.MapGet("/world", () => "Hello world!")
    .WithGroupName("internal");
app.MapGet("/", () => "Hello universe!")
    .WithGroupName("public");

app.Run();

internal sealed class BearerSecuritySchemeTransformer(IAuthenticationSchemeProvider authenticationSchemeProvider) : IOpenApiDocumentTransformer
{
    public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)
    {
        var authenticationSchemes = await authenticationSchemeProvider.GetAllSchemesAsync();
        if (authenticationSchemes.Any(authScheme => authScheme.Name == "Bearer"))
        {
            // Add the security scheme at the document level
            var requirements = new Dictionary<string, OpenApiSecurityScheme>
            {
                ["Bearer"] = new OpenApiSecurityScheme
                {
                    Type = SecuritySchemeType.Http,
                    Scheme = "bearer", // "bearer" refers to the header name here
                    In = ParameterLocation.Header,
                    BearerFormat = "Json Web Token"
                }
            };
            document.Components ??= new OpenApiComponents();
            document.Components.SecuritySchemes = requirements;

            // Apply it as a requirement for all operations
            foreach (var operation in document.Paths.Values.SelectMany(path => path.Operations))
            {
                operation.Value.Security.Add(new OpenApiSecurityRequirement
                {
                    [new OpenApiSecurityScheme { Reference = new OpenApiReference { Id = "Bearer", Type = ReferenceType.SecurityScheme } }] = Array.Empty<string>()
                });
            }
        }
    }
}

Menggunakan transformator operasi

Operasi adalah kombinasi unik jalur dan metode HTTP dalam dokumen OpenAPI. Transformer operasi sangat membantu ketika modifikasi:

  • Harus dibuat untuk setiap titik akhir dalam aplikasi, atau
  • Diterapkan secara kondisional ke rute tertentu.

Transformer operasi memiliki akses ke objek konteks yang berisi:

  • Nama dokumen tempat operasi berada.
  • Yang ApiDescription terkait dengan operasi.
  • yang IServiceProvider digunakan dalam pembuatan dokumen.

Misalnya, transformator operasi berikut menambahkan 500 sebagai kode status respons yang didukung oleh semua operasi dalam dokumen.

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder();

builder.Services.AddAuthentication().AddJwtBearer();

builder.Services.AddOpenApi(options =>
{
    options.UseOperationTransformer((operation, context, cancellationToken) =>
    {
        operation.Responses.Add("500", new OpenApiResponse { Description = "Internal server error" });
        return Task.CompletedTask;
    });
});

var app = builder.Build();

app.MapOpenApi();

app.MapGet("/", () => "Hello world!");

app.Run();

Menggunakan dokumen OpenAPI yang dihasilkan

Dokumen OpenAPI dapat dicolokkan ke ekosistem yang luas dari alat yang ada untuk pengujian, dokumentasi, dan pengembangan lokal.

Menggunakan UI Swagger untuk pengujian ad-hoc lokal

Secara default, Microsoft.AspNetCore.OpenApi paket tidak dikirim dengan dukungan bawaan untuk memvisualisasikan atau berinteraksi dengan dokumen OpenAPI. Alat populer untuk memvisualisasikan atau berinteraksi dengan dokumen OpenAPI termasuk UI Swagger dan ReDoc. UI Swagger dan ReDoc dapat diintegrasikan dalam aplikasi dalam beberapa cara. Editor seperti Visual Studio dan VS Code menawarkan ekstensi dan pengalaman bawaan untuk pengujian terhadap dokumen OpenAPI.

Paket ini Swashbuckle.AspNetCore.SwaggerUi menyediakan bundel aset web UI Swagger untuk digunakan dalam aplikasi. Paket ini dapat digunakan untuk merender UI untuk dokumen yang dihasilkan. Untuk mengonfigurasi ini, instal Swashbuckle.AspNetCore.SwaggerUi paket.

Aktifkan middleware swagger-ui dengan referensi ke rute OpenAPI yang terdaftar sebelumnya. Untuk membatasi pengungkapan informasi dan kerentanan keamanan, hanya aktifkan UI Swagger di lingkungan pengembangan.

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi();
if (app.Environment.IsDevelopment())
{
    app.UseSwaggerUI(options =>
    {
        options.SwaggerEndpoint("/openapi/v1.json", "v1");
    });

}

app.MapGet("/", () => "Hello world!");

app.Run();

Menggunakan Skalar untuk dokumentasi API interaktif

Skalar adalah UI dokumen interaktif sumber terbuka untuk OpenAPI. Skalar dapat diintegrasikan dengan titik akhir OpenAPI yang disediakan oleh ASP.NET Core. Untuk mengonfigurasi Skalar, instal Scalar.AspNetCore paket.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Scalar.AspNetCore;

var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi();

if (app.Environment.IsDevelopment())
{
    app.MapScalarApiReference();
}

app.MapGet("/", () => "Hello world!");

app.Run();

Lint menghasilkan dokumen OpenAPI dengan Spectral

Spectral adalah linter dokumen OpenAPI sumber terbuka. Spectral dapat dimasukkan ke dalam build aplikasi untuk memverifikasi kualitas dokumen OpenAPI yang dihasilkan. Instal Spectral sesuai dengan petunjuk penginstalan paket.

Untuk memanfaatkan Spectral, instal Microsoft.Extensions.ApiDescription.Server paket untuk mengaktifkan pembuatan dokumen OpenAPI build-time.

Aktifkan pembuatan dokumen pada waktu build dengan mengatur properti berikut di file aplikasi .csproj Anda":

<PropertyGroup>
    <OpenApiDocumentsDirectory>$(MSBuildProjectDirectory)</OpenApiDocumentsDirectory>
    <OpenApiGenerateDocuments>true</OpenApiGenerateDocuments>
</PropertyGroup>

Jalankan dotnet build untuk menghasilkan dokumen.

dotnet build

Buat .spectral.yml file dengan konten berikut.

extends: ["spectral:oas"]

Jalankan spectral lint pada file yang dihasilkan.

spectral lint WebMinOpenApi.json
...

The output shows any issues with the OpenAPI document.

```output
1:1  warning  oas3-api-servers       OpenAPI "servers" must be present and non-empty array.
3:10  warning  info-contact           Info object must have "contact" object.                        info
3:10  warning  info-description       Info "description" must be present and non-empty string.       info
9:13  warning  operation-description  Operation "description" must be present and non-empty string.  paths./.get
9:13  warning  operation-operationId  Operation must have "operationId".                             paths./.get

✖ 5 problems (0 errors, 5 warnings, 0 infos, 0 hints)