Sdílet prostřednictvím


Začínáme s Microsoft.AspNetCore.OpenApi

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Balíček Microsoft.AspNetCore.OpenApi poskytuje integrovanou podporu generování dokumentů OpenAPI v ASP.NET Core. Balíček:

Instalace balíčku

Microsoft.AspNetCore.OpenApi Nainstalujte balíček:

V konzole Správce balíčků spusťte následující příkaz:

Install-Package Microsoft.AspNetCore.OpenApi -IncludePrerelease

Konfigurace generování dokumentů OpenAPI

Následující kód:

  • Přidá služby OpenAPI.
  • Povolí koncový bod pro zobrazení dokumentu OpenAPI ve JSformátu ON.
var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi();

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

app.Run();

Spusťte aplikaci a přejděte k https://localhost:<port>/openapi/v1.json zobrazení vygenerovaného dokumentu OpenAPI.

Důležitost názvů dokumentů

Každý dokument OpenAPI v aplikaci má jedinečný název. Výchozí název dokumentu, který je registrován, je v1.

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

Název dokumentu lze upravit předáním názvu jako parametru AddOpenApi volání.

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

Název dokumentu se zobrazí na několika místech v implementaci OpenAPI.

Při načítání vygenerovaného dokumentu OpenAPI je název dokumentu zadaný jako documentName argument parametru v požadavku. Následující žádosti tyto dokumenty a dokumenty vyřeší v1 internal .

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

Možnosti přizpůsobení generování dokumentů OpenAPI

Následující části ukazují, jak přizpůsobit generování dokumentů OpenAPI.

Přizpůsobení verze OpenAPI vygenerovaného dokumentu

Ve výchozím nastavení vytvoří generování dokumentů OpenAPI dokument, který vyhovuje specifikaci OpenAPI verze 3.0. Následující kód ukazuje, jak upravit výchozí verzi dokumentu OpenAPI:

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

Přizpůsobení trasy koncového bodu OpenAPI

Ve výchozím nastavení koncový bod OpenAPI zaregistrovaný prostřednictvím volání pro MapOpenApi zveřejnění dokumentu na koncovém /openapi/{documentName}.json bodu. Následující kód ukazuje, jak přizpůsobit trasu, ve které je dokument OpenAPI zaregistrovaný:

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

Poznámka: Je možné, ale nedoporučuje se odebrat documentName parametr trasy z trasy koncového bodu. documentName Když se parametr trasy odebere ze trasy koncového bodu, architektura se pokusí přeložit název dokumentu z parametru dotazu. Nezadávaní documentName trasy nebo dotazu může vést k neočekávanému chování.

Přizpůsobení koncového bodu OpenAPI

Vzhledem k tomu, že dokument OpenAPI se obsluhuje prostřednictvím koncového bodu obslužné rutiny trasy, je pro koncový bod OpenAPI k dispozici veškeré přizpůsobení, které je dostupné standardním minimálním koncovým bodům.

Přizpůsobení koncových bodů OpenAPI pomocí metadat koncového bodu

Následující seznam ukazuje metadata koncového bodu, která slouží k přizpůsobení vygenerovaného dokumentu OpenAPI:

Další informace o přizpůsobení vygenerovaného dokumentu OpenAPI úpravou metadat koncových bodů najdete v tématu Použití OpenAPI v minimálních aplikacích API.

Omezení přístupu k dokumentům OpenAPI autorizovaným uživatelům

Koncový bod OpenAPI ve výchozím nastavení nepovoluje žádné kontroly autorizace. Je ale možné omezit přístup k dokumentu OpenAPI. Například v následujícím kódu je přístup k dokumentu OpenAPI omezený na ty, které mají tester roli:

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();

Dokument OpenAPI vygenerovaný v mezipaměti

Dokument OpenAPI se znovu vygeneruje při každém odeslání požadavku na koncový bod OpenAPI. Regenerace umožňuje transformátorům začlenit do provozu dynamický stav aplikace. Například opětovné vygenerování požadavku s podrobnostmi o kontextu HTTP. Pokud je to možné, dokument OpenAPI je možné uložit do mezipaměti, aby se zabránilo spuštění kanálu generování dokumentů na každém požadavku 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();

Transformátory dokumentů OpenAPI

Tato část ukazuje, jak přizpůsobit dokumenty OpenAPI pomocí transformátorů.

Přizpůsobení dokumentů OpenAPI pomocí transformátorů

Transformátory poskytují rozhraní API pro úpravu dokumentu OpenAPI s uživatelsky definovanými přizpůsobeními. Transformátory jsou užitečné pro scénáře, jako jsou:

  • Přidání parametrů do všech operací v dokumentu
  • Úprava popisů parametrů nebo operací
  • Přidání informací nejvyšší úrovně do dokumentu OpenAPI

Transformátory spadají do dvou kategorií:

  • Transformátory dokumentů mají přístup k celému dokumentu OpenAPI. Ty se dají použít k provádění globálních úprav dokumentu.
  • Provozní transformátory platí pro každou jednotlivou operaci. Každá jednotlivá operace je kombinací cesty a metody HTTP. Ty se dají použít k úpravě parametrů nebo odpovědí na koncové body.

Transformátory lze zaregistrovat do dokumentu prostřednictvím UseTransformer volání objektu OpenApiOptions . Následující fragment kódu ukazuje různé způsoby registrace transformátorů do dokumentu:

  • Zaregistrujte transformátor dokumentu pomocí delegáta.
  • Registrace transformátoru dokumentu pomocí instance IOpenApiDocumentTransformer.
  • Zaregistrujte transformátor dokumentu pomocí DI-aktivovaného IOpenApiDocumentTransformer.
  • Zaregistrujte transformátor operace pomocí delegáta.
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();

Pořadí provádění pro transformátory

Transformátory se spouštějí v prvním pořadí podle registrace. V následujícím fragmentu kódu má transformátor dokumentu přístup k úpravám provedeným provozním transformátorem:

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();

Použití transformátorů dokumentů

Transformátory dokumentů mají přístup k kontextového objektu, který zahrnuje:

  • Název upravovaného dokumentu.
  • Seznam přidružených k danému ApiDescriptionGroups dokumentu.
  • Použitá IServiceProvider při generování dokumentu.

Transformátory dokumentů mohou také ztlumit dokument OpenAPI, který je generován. Následující příklad ukazuje transformátor dokumentu, který přidává některé informace o rozhraní API do dokumentu 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();

Transformátory dokumentů aktivované službou můžou k úpravě aplikace využívat instance z DI. Následující ukázka ukazuje transformátor dokumentu, který používá IAuthenticationSchemeProvider službu z ověřovací vrstvy. Zkontroluje, jestli jsou v aplikaci zaregistrovaná nějaká schémata související s nosnou knihovnou JWT, a přidá je do nejvyšší úrovně dokumentu 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;
        }
    }
}

Transformátory dokumentů jsou jedinečné pro instanci dokumentu, ke které jsou přidruženy. V následujícím příkladu transformátor:

  • Zaregistruje požadavky související s ověřováním do internal dokumentu.
  • Ponechá public dokument nezměněný.
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>()
                });
            }
        }
    }
}

Použití provozních transformátorů

Operace jsou jedinečné kombinace cest HTTP a metod v dokumentu OpenAPI. Při úpravě jsou užitečné provozní transformátory:

  • Měly by být provedeny do každého koncového bodu v aplikaci, nebo
  • Podmíněné použití u určitých tras.

Transformátory operací mají přístup k objektu kontextu, který obsahuje:

  • Název dokumentu, do které operace patří.
  • Přidružená ApiDescription k operaci.
  • Použitá IServiceProvider při generování dokumentu.

Například následující transformátor operace přidá 500 jako stavový kód odpovědi podporovaný všemi operacemi v dokumentu.

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();

Použití vygenerovaného dokumentu OpenAPI

Dokumenty OpenAPI se můžou zapojit do širokého ekosystému existujících nástrojů pro testování, dokumentaci a místní vývoj.

Použití uživatelského rozhraní Swagger pro místní ad hoc testování

Ve výchozím nastavení Microsoft.AspNetCore.OpenApi se balíček nedoručuje s integrovanou podporou vizualizace nebo interakce s dokumentem OpenAPI. Mezi oblíbené nástroje pro vizualizaci nebo interakci s dokumentem OpenAPI patří uživatelské rozhraní Swagger a ReDoc. Swagger UI a ReDoc je možné integrovat do aplikace několika způsoby. Editory, jako je Visual Studio a VS Code, nabízejí rozšíření a integrovaná prostředí pro testování v dokumentu OpenAPI.

Balíček Swashbuckle.AspNetCore.SwaggerUi poskytuje sadu webových prostředků uživatelského rozhraní Swagger pro použití v aplikacích. Tento balíček lze použít k vykreslení uživatelského rozhraní pro vygenerovaný dokument. Pokud to chcete nakonfigurovat, nainstalujte Swashbuckle.AspNetCore.SwaggerUi balíček.

Povolte middleware swagger-ui s odkazem na trasu OpenAPI zaregistrovanou dříve. Pokud chcete omezit zpřístupnění informací a ohrožení zabezpečení, povolte uživatelské rozhraní Swagger pouze ve vývojových prostředích.

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();

Použití scalaru pro interaktivní dokumentaci k rozhraní API

Scalar je opensourcové interaktivní uživatelské rozhraní dokumentu pro OpenAPI. Skalární se dá integrovat s koncovým bodem OpenAPI poskytovaným ASP.NET Core. Pokud chcete nakonfigurovat Scalar, nainstalujte Scalar.AspNetCore balíček.

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();

Vygenerované dokumenty OpenAPI pomocí lintového rozhraní Spectral

Spectral je opensourcový dokument OpenAPI linter. Spectral je možné začlenit do sestavení aplikace a ověřit kvalitu vygenerovaných dokumentů OpenAPI. Nainstalujte aplikaci Spectral podle pokynů pro instalaci balíčku.

Pokud chcete využít výhod Spectral, nainstalujte Microsoft.Extensions.ApiDescription.Server balíček a povolte generování dokumentů OpenAPI v době sestavení.

Povolte generování dokumentů v době sestavení nastavením následujících vlastností v souboru vaší aplikace .csproj :

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

Spuštěním dotnet build vygenerujte dokument.

dotnet build

Vytvořte .spectral.yml soubor s následujícím obsahem.

extends: ["spectral:oas"]

Spusťte spectral lint vygenerovaný soubor.

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)