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 hetMicrosoft.AspNetCore.OpenApi
-pakket. -
UseSwagger
voegt 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:
- Via de
Produces
-extensiemethode op de node - Via het kenmerk
ProducesResponseType
op de route-handler - Door
TypedResults
vanuit de routehandler te retourneren
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 enTypedResults
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 meerdereIResult
concrete typen retourneert en dat een van deze typen dieIEndpointMetadataProvider
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 hetmultipart/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 kenmerkFromBody
.
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");