Obsługa interfejsu OpenAPI w minimalnych aplikacjach interfejsu API

Specyfikacja interfejsu OpenAPI to niezależny od języka programowania standard do dokumentowania interfejsów API PROTOKOŁU HTTP. Ten standard jest obsługiwany w minimalnych interfejsach API za pośrednictwem kombinacji wbudowanych interfejsów API i bibliotek typu open source. W aplikacji istnieją trzy kluczowe aspekty integracji interfejsu OpenAPI:

  • Generowanie informacji o punktach końcowych w aplikacji.
  • Zbieranie informacji w formacie zgodnym ze schematem OpenAPI.
  • Uwidacznianie wygenerowanego schematu OpenAPI za pomocą wizualnego interfejsu użytkownika lub serializowanego pliku.

Minimalne interfejsy API zapewniają wbudowaną obsługę generowania informacji o punktach końcowych w aplikacji za pośrednictwem Microsoft.AspNetCore.OpenApi pakietu.

Poniższy kod jest generowany przez szablon interfejsu API internetowego ASP.NET Core i używa interfejsu OpenAPI:

using Microsoft.AspNetCore.OpenApi;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

var app = builder.Build();

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

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

app.Run();

internal record WeatherForecast(DateTime Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

W poprzednim wyróżnionym kodzie:

  • AddOpenApi rejestruje usługi wymagane do generowania dokumentów OpenAPI w kontenerze DI aplikacji.
  • MapOpenApi dodaje punkt końcowy do aplikacji do wyświetlania dokumentu OpenAPI serializowanego do wł JS.

Microsoft.AspNetCore.OpenApi Pakiet NuGet

Pakiet Microsoft.AspNetCore.OpenApi udostępnia funkcje, które obejmują następujące funkcje:

  • Obsługa generowania dokumentów OpenAPI w czasie wykonywania i uzyskiwania do nich dostępu za pośrednictwem punktu końcowego w aplikacji
  • Obsługa interfejsów API przekształcania, które umożliwiają modyfikowanie wygenerowanego dokumentu
  • Obsługa generowania dokumentów OpenAPI w czasie kompilacji i serializowania ich na dysku

Microsoft.AspNetCore.OpenApi element jest dodawany jako element PackageReference do pliku projektu:

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

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

  <ItemGroup>    
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.*-*" />
  </ItemGroup>

</Project>

Opisywanie typów odpowiedzi

Interfejs OpenAPI obsługuje podawanie opisu odpowiedzi zwracanych z interfejsu API. Minimalne interfejsy API obsługują trzy strategie ustawiania typu odpowiedzi punktu końcowego:

Metoda Produces rozszerzenia może służyć do dodawania Produces metadanych do punktu końcowego. Jeśli nie podano parametrów, metoda rozszerzenia wypełnia metadane dla docelowego typu w 200 kodzie stanu i application/json typie zawartości.

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

Użycie w TypedResults implementacji programu obsługi tras punktu końcowego automatycznie uwzględnia metadane typu odpowiedzi dla punktu końcowego. Na przykład poniższy kod automatycznie donotuje punkt końcowy z odpowiedzią w 200 kodzie stanu z typem application/json zawartości.

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

Ustawianie odpowiedzi dla ProblemDetails

Podczas ustawiania typu odpowiedzi dla punktów końcowych, które mogą zwrócić odpowiedź ProblemDetails, ProducesProblem metoda rozszerzenia lub TypedResults.Problem może służyć do dodawania odpowiedniej adnotacji do metadanych punktu końcowego.

Jeśli nie ma jawnych adnotacji dostarczonych przez jedną z tych strategii, struktura próbuje określić domyślny typ odpowiedzi, sprawdzając podpis odpowiedzi. Ta domyślna odpowiedź jest wypełniana w kodzie stanu w definicji interfejsu 200 OpenAPI.

Wiele typów odpowiedzi

Jeśli punkt końcowy może zwrócić różne typy odpowiedzi w różnych scenariuszach, możesz podać metadane w następujący sposób:

  • Wywołaj metodę Produces rozszerzenia wiele razy, jak pokazano w poniższym przykładzie:

    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);
    
  • Użyj Results<TResult1,TResult2,TResultN> w podpisie i TypedResults w treści programu obsługi, jak pokazano w poniższym przykładzie:

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

    Results<TResult1,TResult2,TResultN>Typy unii deklarują, że procedura obsługi tras zwraca wiele IResult-implementujących konkretne typy, a każdy z tych typów, które implementująIEndpointMetadataProvider, przyczyni się do metadanych punktu końcowego.

    Typy unii implementują niejawne operatory rzutowania. Te operatory umożliwiają kompilatorowi automatyczne konwertowanie typów określonych w argumentach ogólnych na wystąpienie typu unii. Ta funkcja ma dodatkową korzyść z zapewnienia sprawdzania czasu kompilacji, że program obsługi tras zwraca tylko wyniki, które deklaruje. Próba zwrócenia typu, który nie jest zadeklarowany jako jeden z argumentów ogólnych, aby spowodować Results<TResult1,TResult2,TResultN> błąd kompilacji.

Opisywanie treści i parametrów żądania

Oprócz opisywania typów zwracanych przez punkt końcowy interfejs OpenAPI obsługuje również dodawanie adnotacji do danych wejściowych używanych przez interfejs API. Te dane wejściowe należą do dwóch kategorii:

  • Parametry wyświetlane w ścieżce, ciągu zapytania, nagłówkach lub cookies.
  • Dane przesyłane w ramach treści żądania.

Struktura automatycznie wnioskuje typy parametrów żądania w ścieżce, zapytaniu i ciągu nagłówka na podstawie podpisu procedury obsługi tras.

Aby zdefiniować typ danych wejściowych przesyłanych jako treść żądania, skonfiguruj właściwości przy użyciu Accepts metody rozszerzenia w celu zdefiniowania typu obiektu i typu zawartości oczekiwanego przez procedurę obsługi żądań. W poniższym przykładzie punkt końcowy akceptuje Todo obiekt w treści żądania z oczekiwanym typem application/xmlzawartości .

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

Oprócz metody rozszerzenia typ parametru Acceptsmoże opisywać własną adnotację przez zaimplementowanie interfejsu IEndpointParameterMetadataProvider . Na przykład następujący Todo typ dodaje adnotację, która wymaga treści żądania z typem application/xml zawartości.

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

Jeśli nie podano jawnej adnotacji, platforma próbuje określić domyślny typ żądania, jeśli w procedurze obsługi punktu końcowego istnieje parametr treści żądania. Wnioskowanie używa następujących heurystyki do utworzenia adnotacji:

  • Parametry treści żądania odczytywane z formularza za pośrednictwem atrybutu [FromForm]multipart/form-data są opisane przy użyciu typu zawartości.
  • Wszystkie inne parametry treści żądania są opisane przy użyciu application/json typu zawartości.
  • Treść żądania jest traktowana jako opcjonalna, jeśli jest dopuszczana wartość null lub właściwość AllowEmpty jest ustawiona na atrybucie FromBody .

kod źródłowy interfejsu OpenAPI platformy ASP.NET Core w witrynie GitHub

Dodatkowe zasoby

Specyfikacja interfejsu OpenAPI to niezależny od języka programowania standard do dokumentowania interfejsów API PROTOKOŁU HTTP. Ten standard jest obsługiwany w minimalnych interfejsach API za pośrednictwem kombinacji wbudowanych interfejsów API i bibliotek typu open source. W aplikacji istnieją trzy kluczowe aspekty integracji interfejsu OpenAPI:

  • Generowanie informacji o punktach końcowych w aplikacji.
  • Zbieranie informacji w formacie zgodnym ze schematem OpenAPI.
  • Uwidacznianie wygenerowanego schematu OpenAPI za pomocą wizualnego interfejsu użytkownika lub serializowanego pliku.

Minimalne interfejsy API zapewniają wbudowaną obsługę generowania informacji o punktach końcowych w aplikacji za pośrednictwem Microsoft.AspNetCore.OpenApi pakietu. Uwidacznianie wygenerowanej definicji interfejsu OpenAPI za pomocą wizualnego interfejsu użytkownika wymaga pakietu innej firmy.

Poniższy kod jest generowany przez szablon interfejsu API internetowego ASP.NET Core i używa interfejsu 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);
}

W poprzednim wyróżnionym kodzie:

  • Microsoft.AspNetCore.OpenApi objaśniono w następnej sekcji.
  • AddEndpointsApiExplorer : konfiguruje aplikację tak, aby używała Eksploratora interfejsów API do odnajdywania i opisywania punktów końcowych z domyślnymi adnotacjami. WithOpenApi zastępuje pasujące, domyślne adnotacje wygenerowane przez Eksploratora interfejsów API z utworzonymi z Microsoft.AspNetCore.OpenApi pakietu.
  • UseSwaggerdodaje oprogramowanie pośredniczące struktury Swagger.
  • Element "UseSwaggerUI" umożliwia osadzoną wersję narzędzia Swagger UI.
  • WithName: Element IEndpointNameMetadata w punkcie końcowym jest używany do generowania linków i jest traktowany jako identyfikator operacji w specyfikacji OpenAPI danego punktu końcowego.
  • WithOpenApi w dalszej części tego artykułu wyjaśniono.

Microsoft.AspNetCore.OpenApi Pakiet NuGet

ASP.NET Core udostępnia pakiet do interakcji ze specyfikacjami interfejsu Microsoft.AspNetCore.OpenApi OpenAPI dla punktów końcowych. Pakiet działa jako link między modelami OpenAPI zdefiniowanymi w pakiecie i punktami końcowymi zdefiniowanymi w Microsoft.AspNetCore.OpenApi minimalnych interfejsach API. Pakiet udostępnia interfejs API, który analizuje parametry, odpowiedzi i metadane punktu końcowego w celu konstruowania typu adnotacji interfejsu OpenAPI używanego do opisywania punktu końcowego.

Microsoft.AspNetCore.OpenApi element jest dodawany jako element PackageReference do pliku projektu:

<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>

W przypadku używania z Microsoft.AspNetCore.OpenApiprogramem należy użyć Swashbuckle.AspNetCore programu w Swashbuckle.AspNetCore wersji 6.4.0 lub nowszej. Microsoft.OpenApi 1.4.3 lub nowsza musi być używana do użycia konstruktorów kopii w WithOpenApi wywołaniach.

Dodawanie adnotacji interfejsu OpenAPI do punktów końcowych za pomocą polecenia WithOpenApi

Wywołanie metody WithOpenApi w punkcie końcowym dodaje do metadanych punktu końcowego. Te metadane mogą być następujące:

  • Używane w pakietach innych firm, takich jak Swashbuckle.AspNetCore.
  • Wyświetlane w interfejsie użytkownika struktury Swagger lub w języku YAML lub JSWŁ wygenerowane w celu zdefiniowania interfejsu API.
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();

Modyfikowanie adnotacji interfejsu OpenAPI w pliku WithOpenApi

Metoda WithOpenApi akceptuje funkcję, która może służyć do modyfikowania adnotacji interfejsu OpenAPI. Na przykład w poniższym kodzie opis jest dodawany do pierwszego parametru punktu końcowego:

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

Dodawanie identyfikatorów operacji do interfejsu OpenAPI

Identyfikatory operacji służą do unikatowego identyfikowania danego punktu końcowego w interfejsie OpenAPI. Metodę WithName rozszerzenia można użyć do ustawienia identyfikatora operacji używanego dla metody.

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

Alternatywnie OperationId właściwość można ustawić bezpośrednio w adnotacji OpenAPI.

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

Dodawanie tagów do opisu interfejsu OpenAPI

Interfejs OpenAPI obsługuje kategoryzowanie operacji przy użyciu obiektów tagów . Te tagi są zwykle używane do grupowania operacji w interfejsie użytkownika struktury Swagger. Te tagi można dodać do operacji, wywołując metodę rozszerzenia WithTags w punkcie końcowym z żądanymi tagami.

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

Alternatywnie można ustawić listę adnotacji OpenApiTags OpenAPI za pomocą WithOpenApi metody rozszerzenia.

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

Dodawanie podsumowania lub opisu punktu końcowego

Podsumowanie i opis punktu końcowego można dodać, wywołując metodę WithOpenApi rozszerzenia. W poniższym kodzie podsumowania są ustawiane bezpośrednio w adnotacji interfejsu OpenAPI.

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

Wyklucz opis interfejsu OpenAPI

W poniższym przykładzie /skipme punkt końcowy jest wykluczony z generowania opisu interfejsu 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();

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

app.Run();

Oznaczanie interfejsu API jako przestarzałego

Aby oznaczyć punkt końcowy jako przestarzały, ustaw Deprecated właściwość w adnotacji interfejsu OpenAPI.

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

Opisywanie typów odpowiedzi

Interfejs OpenAPI obsługuje podawanie opisu odpowiedzi zwracanych z interfejsu API. Minimalne interfejsy API obsługują trzy strategie ustawiania typu odpowiedzi punktu końcowego:

Metoda Produces rozszerzenia może służyć do dodawania Produces metadanych do punktu końcowego. Jeśli nie podano parametrów, metoda rozszerzenia wypełnia metadane dla docelowego typu w 200 kodzie stanu i application/json typie zawartości.

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

Użycie w TypedResults implementacji programu obsługi tras punktu końcowego automatycznie uwzględnia metadane typu odpowiedzi dla punktu końcowego. Na przykład poniższy kod automatycznie donotuje punkt końcowy z odpowiedzią w 200 kodzie stanu z typem application/json zawartości.

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

Ustawianie odpowiedzi dla ProblemDetails

Podczas ustawiania typu odpowiedzi dla punktów końcowych, które mogą zwrócić odpowiedź ProblemDetails, ProducesProblem metoda rozszerzenia lub TypedResults.Problem może służyć do dodawania odpowiedniej adnotacji do metadanych punktu końcowego.

Jeśli nie ma jawnych adnotacji dostarczonych przez jedną z powyższych strategii, struktura próbuje określić domyślny typ odpowiedzi, sprawdzając podpis odpowiedzi. Ta domyślna odpowiedź jest wypełniana w kodzie stanu w definicji interfejsu 200 OpenAPI.

Wiele typów odpowiedzi

Jeśli punkt końcowy może zwrócić różne typy odpowiedzi w różnych scenariuszach, możesz podać metadane w następujący sposób:

  • Wywołaj metodę Produces rozszerzenia wiele razy, jak pokazano w poniższym przykładzie:

    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);
    
  • Użyj Results<TResult1,TResult2,TResultN> w podpisie i TypedResults w treści programu obsługi, jak pokazano w poniższym przykładzie:

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

    Results<TResult1,TResult2,TResultN>Typy unii deklarują, że procedura obsługi tras zwraca wiele IResult-implementujących konkretne typy, a każdy z tych typów, które implementująIEndpointMetadataProvider, przyczyni się do metadanych punktu końcowego.

    Typy unii implementują niejawne operatory rzutowania. Te operatory umożliwiają kompilatorowi automatyczne konwertowanie typów określonych w argumentach ogólnych na wystąpienie typu unii. Ta funkcja ma dodatkową korzyść z zapewnienia sprawdzania czasu kompilacji, że program obsługi tras zwraca tylko wyniki, które deklaruje. Próba zwrócenia typu, który nie jest zadeklarowany jako jeden z argumentów ogólnych, aby spowodować Results<TResult1,TResult2,TResultN> błąd kompilacji.

Opisywanie treści i parametrów żądania

Oprócz opisywania typów zwracanych przez punkt końcowy interfejs OpenAPI obsługuje również dodawanie adnotacji do danych wejściowych używanych przez interfejs API. Te dane wejściowe należą do dwóch kategorii:

  • Parametry wyświetlane w ścieżce, ciągu zapytania, nagłówkach lub cookies
  • Dane przesyłane w ramach treści żądania

Struktura automatycznie wnioskuje typy parametrów żądania w ścieżce, zapytaniu i ciągu nagłówka na podstawie podpisu procedury obsługi tras.

Aby zdefiniować typ danych wejściowych przesyłanych jako treść żądania, skonfiguruj właściwości przy użyciu Accepts metody rozszerzenia w celu zdefiniowania typu obiektu i typu zawartości oczekiwanego przez procedurę obsługi żądań. W poniższym przykładzie punkt końcowy akceptuje Todo obiekt w treści żądania z oczekiwanym typem application/xmlzawartości .

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

Oprócz metody rozszerzenia typ parametru Accepts może opisywać własną adnotację przez zaimplementowanie interfejsu IEndpointParameterMetadataProvider . Na przykład następujący Todo typ dodaje adnotację, która wymaga treści żądania z typem application/xml zawartości.

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

Jeśli nie podano jawnej adnotacji, platforma próbuje określić domyślny typ żądania, jeśli w procedurze obsługi punktu końcowego istnieje parametr treści żądania. Wnioskowanie używa następujących heurystyki do utworzenia adnotacji:

  • Parametry treści żądania odczytywane z formularza za pośrednictwem atrybutu [FromForm]multipart/form-data są opisane przy użyciu typu zawartości.
  • Wszystkie inne parametry treści żądania są opisane przy użyciu application/json typu zawartości.
  • Treść żądania jest traktowana jako opcjonalna, jeśli jest dopuszczana wartość null lub właściwość AllowEmpty jest ustawiona na atrybucie FromBody .

Obsługa wersji interfejsu API

Minimalne interfejsy API obsługują przechowywanie wersji interfejsu API za pośrednictwem pakietu Asp.Versioning.Http. Przykłady konfigurowania wersji przy użyciu minimalnych interfejsów API można znaleźć w repozytorium przechowywania wersji interfejsu API.

kod źródłowy interfejsu OpenAPI platformy ASP.NET Core w witrynie GitHub

Dodatkowe zasoby

Aplikacja może opisać specyfikację interfejsu OpenAPI dla procedur obsługi tras przy użyciu struktury Swashbuckle.

Poniższy kod to typowa aplikacja ASP.NET Core z obsługą interfejsu OpenAPI:

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

Wyklucz opis interfejsu OpenAPI

W poniższym przykładzie /skipme punkt końcowy jest wykluczony z generowania opisu interfejsu OpenAPI:

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

Opisywanie typów odpowiedzi

W poniższym przykładzie użyto wbudowanych typów wyników, aby dostosować odpowiedź:

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

Dodawanie identyfikatorów operacji do interfejsu OpenAPI

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

Dodawanie tagów do opisu interfejsu OpenAPI

Poniższy kod używa tagu grupowania interfejsu OpenAPI:

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