Delen via


OpenAPI-documenten genereren

Het Microsoft.AspNetCore.OpenApi-pakket biedt ingebouwde ondersteuning voor het genereren van OpenAPI-documenten in ASP.NET Core. Het pakket biedt de volgende functies:

  • Ondersteuning voor het genereren van OpenAPI-documenten tijdens runtime en het openen ervan via een eindpunt in de toepassing.
  • Ondersteuning voor 'transformer'-API's waarmee het gegenereerde document kan worden gewijzigd.
  • Ondersteuning voor het genereren van meerdere OpenAPI-documenten vanuit één app.
  • Maakt gebruik van JSON-schemaondersteuning die wordt geboden door System.Text.Json.
  • Is compatibel met systeemeigen AoT.

Pakketinstallatie

Installeer het Microsoft.AspNetCore.OpenApi-pakket:

Voer de volgende opdracht uit vanuit de Package Manager Console:

Install-Package Microsoft.AspNetCore.OpenApi

Het genereren van OpenAPI-documenten configureren

De volgende code:

  • Hiermee worden OpenAPI-services toegevoegd met behulp van de extensiemethode AddOpenApi in de serviceverzameling van de app-builder.
  • Hiermee wordt een eindpunt toegewezen voor het weergeven van het OpenAPI-document in JSON-indeling met de extensiemethode MapOpenApi in de app.
var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi();

var app = builder.Build();

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

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

app.Run();

Start de app en navigeer naar https://localhost:<port>/openapi/v1.json om het gegenereerde OpenAPI-document weer te geven.

Opties voor het aanpassen van het genereren van OpenAPI-documenten

In de volgende secties ziet u hoe u het genereren van OpenAPI-documenten kunt aanpassen.

De naam van het OpenAPI-document aanpassen

Elk OpenAPI-document in een app heeft een unieke naam. De standaarddocumentnaam die is geregistreerd, is v1.

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

De documentnaam kan worden gewijzigd door de naam als parameter door te geven aan de AddOpenApi aanroep.

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

De documentnaam wordt op verschillende plaatsen in de OpenAPI-implementatie weergegeven.

Bij het ophalen van het gegenereerde OpenAPI-document wordt de documentnaam opgegeven als de parameter documentName in het verzoek. De volgende verzoeken lossen de v1- en internal-documenten op.

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

De OpenAPI-versie van een gegenereerd document aanpassen

Standaard maakt het genereren van OpenAPI-documenten een document dat compatibel is met v3.0 van de OpenAPI-specificatie. De volgende code laat zien hoe u de standaardversie van het OpenAPI-document wijzigt:

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

De Route van het OpenAPI-eindpunt aanpassen

Standaard maakt het OpenAPI-eindpunt dat is geregistreerd via een aanroep naar MapOpenApi het document toegankelijk op het /openapi/{documentName}.json-eindpunt. De volgende code laat zien hoe u de route kunt aanpassen waarop het OpenAPI-document is geregistreerd:

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

Het is mogelijk, maar niet aanbevolen, om de documentName routeparameter uit de eindpuntroute te verwijderen. Wanneer de documentName routeparameter wordt verwijderd uit de eindpuntroute, probeert het framework de documentnaam op te lossen uit de queryparameter. Het niet opgeven van de documentName in de route of query kan leiden tot onverwacht gedrag.

Het OpenAPI-eindpunt aanpassen

Omdat het OpenAPI-document wordt geleverd via een routehandlereindpunt, is elke aanpassing die beschikbaar is voor standaard minimale eindpunten beschikbaar voor het OpenAPI-eindpunt.

OpenAPI-documenttoegang beperken tot geautoriseerde gebruikers

Het OpenAPI-eindpunt schakelt standaard geen autorisatiecontroles in. Autorisatiecontroles kunnen echter worden toegepast op het OpenAPI-document. In de volgende code is de toegang tot het OpenAPI-document beperkt tot personen met de rol tester:

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

Door cache gegenereerd OpenAPI-document

Het OpenAPI-document wordt telkens opnieuw gegenereerd wanneer een aanvraag naar het OpenAPI-eindpunt wordt verzonden. Met regeneratie kunnen transformatoren dynamische toepassingsstatus opnemen in hun werking. Bijvoorbeeld het opnieuw genereren van een aanvraag met details van de HTTP-context. Indien van toepassing kan het OpenAPI-document in de cache worden opgeslagen om te voorkomen dat de pijplijn voor het genereren van documenten op elke HTTP-aanvraag wordt uitgevoerd.

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

if (app.Environment.IsDevelopment())
{
    app.MapOpenApi()
        .CacheOutput();
}

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

app.Run();

Meerdere OpenAPI-documenten genereren

In sommige scenario's is het handig om meerdere OpenAPI-documenten te genereren met verschillende inhoud van één ASP.NET Core API-app. Deze scenario's omvatten:

  • OpenAPI-documentatie genereren voor verschillende doelgroepen, zoals openbare en interne API's.
  • OpenAPI-documentatie genereren voor verschillende versies van een API.
  • OpenAPI-documentatie genereren voor verschillende onderdelen van een toepassing, zoals een front-end- en back-end-API.

Als u meerdere OpenAPI-documenten wilt genereren, roept u de AddOpenApi-extensiemethode eenmaal aan voor elk document, waarbij u telkens een andere documentnaam opgeeft in de eerste parameter.

builder.Services.AddOpenApi("v1");
builder.Services.AddOpenApi("v2");

Elke aanroep van AddOpenApi kan een eigen set opties opgeven, zodat u dezelfde of verschillende aanpassingen voor elk OpenAPI-document kunt gebruiken.

Het framework maakt gebruik van de ShouldInclude delegatiemethode van OpenApiOptions om te bepalen welke eindpunten in elk document moeten worden opgenomen.

Voor elk document wordt de ShouldInclude gedelegeerde methode aangeroepen voor elk eindpunt in de toepassing, waarbij het ApiDescription-object voor het eindpunt wordt doorgegeven. De methode retourneert een Booleaanse waarde die aangeeft of het eindpunt in het document moet worden opgenomen. Het ApiDescription-object bevat informatie over het eindpunt, zoals de HTTP-methode, route en antwoordtypen, evenals metagegevens die zijn gekoppeld aan het eindpunt via kenmerken of extensiemethoden.

De standaard implementatie van deze gemachtigde maakt gebruik van het GroupName veld van ApiDescription, dat is ingesteld op een eindpunt met behulp van de WithGroupName extensiemethode of het kenmerk EndpointGroupNameAttribute, om te bepalen welke eindpunten in het document moeten worden opgenomen. Elk eindpunt waaraan geen groepsnaam is toegewezen, bevat alle OpenAPI-documenten.

    // Include endpoints without a group name or with a group name that matches the document name
    ShouldInclude = (description) => description.GroupName == null || description.GroupName == DocumentName;    

U kunt de ShouldInclude delegeringsmethode aanpassen om eindpunten op te nemen of uit te sluiten op basis van de criteria die u kiest.

OpenAPI-documenten genereren tijdens de build

In typische webtoepassingen worden OpenAPI-documenten gegenereerd tijdens runtime en geleverd via een HTTP-aanvraag naar de toepassingsserver.

In sommige scenario's is het handig om het OpenAPI-document te genereren tijdens de buildstap van de toepassing. Deze scenario's omvatten:

  • OpenAPI-documentatie genereren die wordt opgeslagen in versiebeheer.
  • OpenAPI-documentatie genereren die wordt gebruikt voor op spec gebaseerde integratietests.
  • OpenAPI-documentatie genereren die statisch wordt geleverd vanaf de webserver.

Als u ondersteuning wilt toevoegen voor het genereren van OpenAPI-documenten tijdens de build, installeert u het Microsoft.Extensions.ApiDescription.Server-pakket:

Voer de volgende opdracht uit vanuit de Package Manager Console:

Install-Package Microsoft.Extensions.ApiDescription.Server

Bij de installatie genereert dit pakket automatisch de Open API-documenten die tijdens de build aan de toepassing zijn gekoppeld en vullen deze in de uitvoermap van de toepassing.

$ dotnet build
$ cat bin/Debug/net9.0/{ProjectName}.json

Het aanpassen van de generatie van build-time documenten

De uitvoermap van het gegenereerde Open API-bestand wijzigen

Standaard wordt het gegenereerde OpenAPI-document verzonden naar de uitvoermap van de toepassing. Als u de locatie van het verzonden bestand wilt wijzigen, stelt u het doelpad in de eigenschap OpenApiDocumentsDirectory in.

<PropertyGroup>
  <OpenApiDocumentsDirectory>.</OpenApiDocumentsDirectory>
</PropertyGroup>

De waarde van OpenApiDocumentsDirectory wordt bepaald ten opzichte van het projectbestand. Als u de bovenstaande . waarde gebruikt, wordt het OpenAPI-document verzonden in dezelfde map als het projectbestand.

De naam van het uitvoerbestand wijzigen

Het gegenereerde OpenAPI-document heeft standaard dezelfde naam als het projectbestand van de toepassing. Als u de naam van het verzonden bestand wilt wijzigen, stelt u het argument --file-name in de eigenschap OpenApiGenerateDocumentsOptions in.

<PropertyGroup>
  <OpenApiGenerateDocumentsOptions>--file-name my-open-api</OpenApiGenerateDocumentsOptions>
</PropertyGroup>

Het OpenAPI-document selecteren dat moet worden gegenereerd

Sommige toepassingen kunnen worden geconfigureerd om meerdere OpenAPI-documenten te verzenden, voor verschillende versies van een API of om onderscheid te maken tussen openbare en interne API's. Standaard verzendt de build-time documentgenerator bestanden voor alle documenten die zijn geconfigureerd in een toepassing. Als u slechts één documentnaam wilt verzenden, stelt u het argument --document-name in de eigenschap OpenApiGenerateDocumentsOptions in.

<PropertyGroup>
  <OpenApiGenerateDocumentsOptions>--document-name v2</OpenApiGenerateDocumentsOptions>
</PropertyGroup>

Runtimegedrag aanpassen tijdens het genereren van build-time-documenten

Functies voor het genereren van OpenAPI-documenten tijdens de build-tijd door het toegangspunt van de app te starten met een mockserver-implementatie. Er is een mockserver vereist om nauwkeurige OpenAPI-documenten te produceren, omdat alle informatie in het OpenAPI-document niet statisch kan worden geanalyseerd. Omdat het toegangspunt voor apps wordt aangeroepen, wordt elke logica in het opstarten van de apps aangeroepen. Dit omvat code die services injecteert in de DI-container of uit de configuratie leest. In sommige scenario's is het nodig om de codepaden te beperken die worden uitgevoerd wanneer het toegangspunt van apps wordt aangeroepen tijdens de build-time-documentgeneratie. Deze scenario's omvatten:

  • Niet lezen uit bepaalde configuratiereeksen.
  • Databasegerelateerde services worden niet geregistreerd.

Om te voorkomen dat deze codepaden worden aangeroepen door de build-time generatiepijplijn, kunnen ze worden geconditioneerd op basis van een controle van de invoerassembly.

using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

if (Assembly.GetEntryAssembly()?.GetName().Name != "GetDocument.Insider")
{
    builder.AddServiceDefaults();
}

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    app.UseHsts();
}

var myKeyValue = app.Configuration["MyKey"];

app.MapGet("/", () => {
    return Results.Ok($"The value of MyKey is: {myKeyValue}");
})
.WithName("TestKey");

app.Run();

AddServiceDefaults voegt algemene .NET Aspire-services toe, zoals servicedetectie, tolerantie, statuscontroles en OpenTelemetry.

Bijsnijden en systeemeigen AOT

OpenAPI in ASP.NET Core biedt ondersteuning voor bijsnijden en systeemeigen AOT. Met de volgende stappen maakt en publiceert u een OpenAPI-app met bijsnijden en systeemeigen AOT:

Maak een nieuw ASP.NET Core Web API-project (Native AOT).

dotnet new webapiaot

Voeg het Microsoft.AspNetCore.OpenAPI-pakket toe.

dotnet add package Microsoft.AspNetCore.OpenApi --prerelease

Werk Program.cs bij om het genereren van OpenAPI-documenten in te schakelen.

+ builder.Services.AddOpenApi();

var app = builder.Build();

+ app.MapOpenApi();

Publiceer de app.

dotnet publish

Minimale API's bieden ingebouwde ondersteuning voor het genereren van informatie over eindpunten in een app via het Microsoft.AspNetCore.OpenApi-pakket. Voor het beschikbaar maken van de gegenereerde OpenAPI-definitie via een visuele gebruikersinterface is een pakket van derden vereist. Zie de .NET 9-versie van dit artikelvoor meer informatie over ondersteuning voor OpenAPI in op controller gebaseerde API's.

De volgende code wordt gegenereerd door de ASP.NET Core minimale web-API-sjabloon en maakt gebruik van OpenAPI:

using Microsoft.AspNetCore.OpenApi;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

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.MapGet("/weatherforecast", () =>
{
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            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(DateTime Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

In de eerder genoemde gemarkeerde code:

  • Microsoft.AspNetCore.OpenApi wordt uitgelegd in de volgende sectie.
  • AddEndpointsApiExplorer: hiermee configureert u de app om de API Explorer te gebruiken voor het detecteren en beschrijven van eindpunten met standaardaantekeningen. WithOpenApi vervangt overeenkomende standaardaantekeningen die door de API Explorer worden gegenereerd met de aantekeningen die zijn geproduceerd uit het Microsoft.AspNetCore.OpenApi-pakket.
  • UseSwaggervoegt de Swagger middleware toe.
  • UseSwaggerUI maakt een ingesloten versie van het Swagger UI-hulpprogramma mogelijk.
  • WithName: de IEndpointNameMetadata op het eindpunt wordt gebruikt voor het genereren van koppelingen en wordt behandeld als de bewerkings-id in de OpenAPI-specificatie van het opgegeven eindpunt.
  • WithOpenApi wordt verderop in dit artikel uitgelegd.

Microsoft.AspNetCore.OpenApi NuGet-pakket

ASP.NET Core biedt het Microsoft.AspNetCore.OpenApi-pakket voor interactie met OpenAPI-specificaties voor eindpunten. Het pakket fungeert als een koppeling tussen de OpenAPI-modellen die zijn gedefinieerd in het Microsoft.AspNetCore.OpenApi-pakket en de eindpunten die zijn gedefinieerd in minimale API's. Het pakket biedt een API waarmee de parameters, antwoorden en metagegevens van een eindpunt worden onderzocht om een OpenAPI-aantekeningstype te maken dat wordt gebruikt om een eindpunt te beschrijven.

Microsoft.AspNetCore.OpenApi wordt toegevoegd als packageReference aan een projectbestand:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>    
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.*-*" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
  </ItemGroup>

</Project>

Wanneer u Swashbuckle.AspNetCore gebruikt met Microsoft.AspNetCore.OpenApi, moet Swashbuckle.AspNetCore 6.4.0 of hoger worden gebruikt. Microsoft.OpenApi 1.4.3 of hoger moet worden gebruikt om te profiteren van kopieerconstructors in WithOpenApi-oproepen.

OpenAPI-aantekeningen toevoegen aan eindpunten via WithOpenApi

Het aanroepen van WithOpenApi op het eindpunt voegt toe aan de metagegevens van het eindpunt. Dit kunnen de volgende metagegevens zijn:

  • Wordt gebruikt in pakketten van derden, zoals Swashbuckle.AspNetCore.
  • Wordt weergegeven in de Swagger-gebruikersinterface of in YAML of JSON die is gegenereerd om de API te definiëren.
app.MapPost("/todoitems/{id}", async (int id, Todo todo, TodoDb db) =>
{
    todo.Id = id;
    db.Todos.Add(todo);
    await db.SaveChangesAsync();

    return Results.Created($"/todoitems/{todo.Id}", todo);
})
.WithOpenApi();

De OpenAPI-aantekening wijzigen in WithOpenApi

De methode WithOpenApi accepteert een functie die kan worden gebruikt om de OpenAPI-aantekening te wijzigen. In de volgende code wordt bijvoorbeeld een beschrijving toegevoegd aan de eerste parameter van het eindpunt:

app.MapPost("/todo2/{id}", async (int id, Todo todo, TodoDb db) =>
{
    todo.Id = id;
    db.Todos.Add(todo);
    await db.SaveChangesAsync();

    return Results.Created($"/todoitems/{todo.Id}", todo);
})
.WithOpenApi(generatedOperation =>
{
    var parameter = generatedOperation.Parameters[0];
    parameter.Description = "The ID associated with the created Todo";
    return generatedOperation;
});

Bewerkings-id's toevoegen aan OpenAPI

Bewerkings-id's worden gebruikt om een bepaald eindpunt in OpenAPI uniek te identificeren. De WithName-extensiemethode kan worden gebruikt om de bewerkings-id in te stellen die wordt gebruikt voor een methode.

app.MapGet("/todoitems2", async (TodoDb db) =>
    await db.Todos.ToListAsync())
    .WithName("GetToDoItems");

U kunt ook de eigenschap OperationId rechtstreeks instellen op de OpenAPI-aantekening.

app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
    .WithOpenApi(operation => new(operation)
    {
        OperationId = "GetTodos"
    });

Tags toevoegen aan de OpenAPI-beschrijving

OpenAPI ondersteunt het gebruik van tagobjecten om bewerkingen te categoriseren. Deze tags worden doorgaans gebruikt voor het groeperen van bewerkingen in de Swagger-gebruikersinterface. Deze tags kunnen worden toegevoegd aan een bewerking door de WithTags extensiemethode op het eindpunt aan te roepen met de gewenste tags.

app.MapGet("/todoitems", async (TodoDb db) =>
    await db.Todos.ToListAsync())
    .WithTags("TodoGroup");

U kunt ook de lijst met OpenApiTags instellen op de OpenAPI-aantekening via de WithOpenApi-extensiemethode.

app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
    .WithOpenApi(operation => new(operation)
    {
        Tags = new List<OpenApiTag> { new() { Name = "Todos" } }
    });

Eindpuntsamenvatting of beschrijving toevoegen

Het overzicht en de beschrijving van het eindpunt kunnen worden toegevoegd door de uitbreidingsmethode WithOpenApi aan te roepen. In de volgende code worden de samenvattingen rechtstreeks op de OpenAPI-aantekening ingesteld.

app.MapGet("/todoitems2", async (TodoDb db) => await db.Todos.ToListAsync())
    .WithOpenApi(operation => new(operation)
    {
        Summary = "This is a summary",
        Description = "This is a description"
    });

OpenAPI-beschrijving uitsluiten

In het volgende voorbeeld wordt het /skipme-eindpunt uitgesloten van het genereren van een OpenAPI-beschrijving:

using Microsoft.AspNetCore.OpenApi;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.MapGet("/swag", () => "Hello Swagger!")
    .WithOpenApi();
app.MapGet("/skipme", () => "Skipping Swagger.")
                    .ExcludeFromDescription();

app.Run();

Een API markeren als verouderd

Als u een eindpunt als verouderd wilt markeren, stelt u de eigenschap Deprecated in op de OpenAPI-aantekening.

app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
    .WithOpenApi(operation => new(operation)
    {
        Deprecated = true
    });

Antwoordtypen beschrijven

OpenAPI biedt ondersteuning voor een beschrijving van de antwoorden die worden geretourneerd door een API. Minimale API's ondersteunen drie strategieën voor het instellen van het antwoordtype van een eindpunt:

De Produces-extensiemethode kan worden gebruikt om Produces metagegevens toe te voegen aan een eindpunt. Wanneer er geen parameters worden opgegeven, vult de extensiemethode metagegevens voor het doeltype onder een 200 statuscode en een application/json inhoudstype.

app
    .MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
    .Produces<IList<Todo>>();

Het gebruik van TypedResults in de implementatie van de route-handler van een eindpunt bevat automatisch de metagegevens van het antwoordtype voor het eindpunt. De volgende code annoteert bijvoorbeeld automatisch het eindpunt met een antwoord bij de statuscode 200 en een contenttype application/json.

app.MapGet("/todos", async (TodoDb db) =>
{
    var todos = await db.Todos.ToListAsync());
    return TypedResults.Ok(todos);
});

Antwoorden instellen voor ProblemDetails

Wanneer u het antwoordtype instelt voor eindpunten die mogelijk een ProblemDetails-antwoord retourneren, kan de ProducesProblem-extensiemethode, ProducesValidationProblemof TypedResults.Problem worden gebruikt om de juiste aantekening toe te voegen aan de metagegevens van het eindpunt. Houd er rekening mee dat de ProducesProblem- en ProducesValidationProblem-extensiemethoden niet kunnen worden gebruikt met routegroepen in .NET 8 en eerder.

Wanneer een van de bovenstaande strategieën geen expliciete aantekeningen bevat, probeert het framework een standaardantwoordtype te bepalen door de handtekening van het antwoord te onderzoeken. Dit standaardantwoord wordt ingevuld onder de 200 statuscode in de OpenAPI-definitie.

Meerdere antwoordtypen

Als een eindpunt verschillende antwoordtypen in verschillende scenario's kan retourneren, kunt u op de volgende manieren metagegevens opgeven:

  • Roep de Produces-extensiemethode meerdere keren aan, zoals wordt weergegeven in het volgende voorbeeld:

    app.MapGet("/api/todoitems/{id}", async (int id, TodoDb db) =>
             await db.Todos.FindAsync(id) 
             is Todo todo
             ? Results.Ok(todo) 
             : Results.NotFound())
       .Produces<Todo>(StatusCodes.Status200OK)
       .Produces(StatusCodes.Status404NotFound);
    
  • Gebruik Results<TResult1,TResult2,TResultN> in de handtekening en TypedResults in de hoofdtekst van de handler, zoals wordt weergegeven in het volgende voorbeeld:

    app.MapGet("/book/{id}", Results<Ok<Book>, NotFound> (int id, List<Book> bookList) =>
    {
        return bookList.FirstOrDefault((i) => i.Id == id) is Book book
         ? TypedResults.Ok(book)
         : TypedResults.NotFound();
    });
    

    De Results<TResult1,TResult2,TResultN>samenvoegtypen declareren dat een route-handler meerdere IResultconcrete typen retourneert en dat een van deze typen die IEndpointMetadataProvider implementeren, bijdraagt aan de metagegevens van het eindpunt.

    De samenvoegtypen implementeren impliciete cast-operators. Met deze operators kan de compiler automatisch de typen converteren die zijn opgegeven in de algemene argumenten naar een exemplaar van het samenvoegtype. Deze mogelijkheid heeft het extra voordeel van het bieden van compileertijdcontrole dat een route-handler alleen de resultaten retourneert die het declareert. Als u probeert een type te retourneren dat niet is gedeclareerd als een van de algemene argumenten voor Results<TResult1,TResult2,TResultN> resulteert in een compilatiefout.

Hoofdtekst en parameters van de aanvraag beschrijven

Naast het beschrijven van de typen die worden geretourneerd door een eindpunt, biedt OpenAPI ook ondersteuning voor het toevoegen van aantekeningen bij de invoer die wordt gebruikt door een API. Deze invoer wordt onderverdeeld in twee categorieën:

  • Parameters die worden weergegeven in het pad, querytekenreeks, headers of cookies
  • Gegevens die worden verzonden als onderdeel van de aanvraagbody

In het framework worden de typen voor aanvraagparameters in het pad, de query en de header automatisch afgeleid op basis van de signatuur van de route-handler.

Als u het type invoer wilt definiëren dat wordt verzonden als de aanvraagbody, configureert u de eigenschappen met behulp van de Accepts-extensiemethode om het objecttype en inhoudstype te definiëren dat wordt verwacht door de aanvraaghandler. In het volgende voorbeeld accepteert het eindpunt een Todo object in de aanvraagbody met een verwacht inhoudstype van application/xml.

app.MapPost("/todos/{id}", (int id, Todo todo) => ...)
  .Accepts<Todo>("application/xml");

Naast de Accepts-extensiemethode kan een parametertype een eigen aantekening beschrijven door de IEndpointParameterMetadataProvider-interface te implementeren. Bijvoorbeeld wordt met het volgende Todo type een aantekening toegevoegd waarvoor een aanvraagtekst met een application/xml-inhoudstype is vereist.

public class Todo : IEndpointParameterMetadataProvider
{
    public static void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder)
    {
        builder.Metadata.Add(new ConsumesAttribute(typeof(Todo), isOptional: false, "application/xml"));
    }
}

Wanneer er geen expliciete aantekening wordt opgegeven, probeert het framework het standaardaanvraagtype te bepalen als er een aanvraagbodyparameter in de eindpunthandler staat. De deductie gebruikt de volgende heuristieken om de aantekening te produceren:

  • Hoofdtekstparameters van de aanvraag die vanuit een formulier worden gelezen via het kenmerk [FromForm] worden beschreven met het multipart/form-data inhoudstype.
  • Alle andere parameters voor de aanvraagbody worden beschreven met het application/json inhoudstype.
  • De aanvraagbody wordt behandeld als optioneel als deze null kan zijn of als de eigenschap AllowEmpty is ingesteld op het kenmerk FromBody.

Ondersteuning voor API-versiebeheer

Minimale API's ondersteunen API-versiebeheer via het Asp.Versioning.Http-pakket. Voorbeelden van het configureren van versiebeheer met minimale API's vindt u in de OPSLAGPLAATS voor API-versiebeheer.

ASP.NET Core OpenAPI-broncode op GitHub

Aanvullende informatiebronnen

Een minimale API-app kan de OpenAPI-specificatie voor route-handlers beschrijven met behulp van Swashbuckle.

Zie de .NET 9-versie van dit artikelvoor meer informatie over ondersteuning voor OpenAPI in op controller gebaseerde API's.

De volgende code is een typische ASP.NET Core-app met OpenAPI-ondersteuning:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new() { Title = builder.Environment.ApplicationName,
                               Version = "v1" });
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger(); // UseSwaggerUI Protected by if (env.IsDevelopment())
    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
                                    $"{builder.Environment.ApplicationName} v1"));
}

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

app.Run();

OpenAPI-beschrijving uitsluiten

In het volgende voorbeeld wordt het /skipme-eindpunt uitgesloten van het genereren van een OpenAPI-beschrijving:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(); // UseSwaggerUI Protected by if (env.IsDevelopment())
}

app.MapGet("/swag", () => "Hello Swagger!");
app.MapGet("/skipme", () => "Skipping Swagger.")
                    .ExcludeFromDescription();

app.Run();

Antwoordtypen beschrijven

In het volgende voorbeeld worden de ingebouwde resultaattypen gebruikt om het antwoord aan te passen:

app.MapGet("/api/todoitems/{id}", async (int id, TodoDb db) =>
         await db.Todos.FindAsync(id) 
         is Todo todo
         ? Results.Ok(todo) 
         : Results.NotFound())
   .Produces<Todo>(StatusCodes.Status200OK)
   .Produces(StatusCodes.Status404NotFound);

Bewerkings-id's toevoegen aan OpenAPI

app.MapGet("/todoitems2", async (TodoDb db) =>
    await db.Todos.ToListAsync())
    .WithName("GetToDoItems");

Tags toevoegen aan de OpenAPI-beschrijving

De volgende code maakt gebruik van een OpenAPI-groeperingstag:

app.MapGet("/todoitems", async (TodoDb db) =>
    await db.Todos.ToListAsync())
    .WithTags("TodoGroup");