Aracılığıyla paylaş


Microsoft.AspNetCore.OpenApi ile çalışmaya başlama

Paket, Microsoft.AspNetCore.OpenApi ASP.NET Core'da OpenAPI belge oluşturma için yerleşik destek sağlar. Paket:

  • Yerel AoT ile uyumludur.
  • tarafından System.Text.Jsonsağlanan ON şema desteğinden JSyararlanır.
  • Oluşturulan belgeleri değiştirmek için transformatörLER API'sini sağlar.
  • Tek bir uygulama içinde birden çok OpenAPI belgesini yönetmeyi destekler.

Paket yükleme

Microsoft.AspNetCore.OpenApi Paketi yükleyin:

Paket Yöneticisi Konsolu'ndan aşağıdaki komutu çalıştırın:

Install-Package Microsoft.AspNetCore.OpenApi -IncludePrerelease

OpenAPI belge oluşturmayı yapılandırma

Aşağıdaki kod:

  • OpenAPI hizmetleri ekler.
  • OpenAPI belgesini JSON biçiminde görüntülemek için uç noktayı etkinleştirir.
var builder = WebApplication.CreateBuilder();

builder.Services.AddOpenApi();

var app = builder.Build();

app.MapOpenApi();

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

app.Run();

Uygulamayı başlatın ve oluşturulan OpenAPI belgesini görüntülemek için adresine gidin https://localhost:<port>/openapi/v1.json .

Belge adlarının önemi

Bir uygulamadaki her OpenAPI belgesinin benzersiz bir adı vardır. Kaydedilen varsayılan belge adıdır v1.

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

Belge adı, çağrıya AddOpenApi parametre olarak geçirilerek değiştirilebilir.

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

Belge adı, OpenAPI uygulamasında çeşitli yerlerde görünür.

Oluşturulan OpenAPI belgesi getirilirken, belge adı istekte documentName parametre bağımsız değişkeni olarak sağlanır. Aşağıdaki istekler ve internal belgelerini çözümlerv1.

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

OpenAPI belge oluşturmayı özelleştirme seçenekleri

Aşağıdaki bölümlerde OpenAPI belge oluşturma işleminin nasıl özelleştirileceği gösterilmektedir.

Oluşturulan belgenin OpenAPI sürümünü özelleştirme

Varsayılan olarak, OpenAPI belge oluşturma, OpenAPI belirtiminin v3.0 ile uyumlu bir belge oluşturur. Aşağıdaki kod, OpenAPI belgesinin varsayılan sürümünün nasıl değiştirileceği gösterilmektedir:

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

OpenAPI uç noktası yolunu özelleştirme

Varsayılan olarak, çağrı MapOpenApi yoluyla kaydedilen OpenAPI uç noktası belgeyi /openapi/{documentName}.json uç noktada kullanıma sunar. Aşağıdaki kodda, OpenAPI belgesinin kaydedildiği yolun nasıl özelleştirileceği gösterilmektedir:

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

Not: Yol parametresini uç nokta yolundan documentName kaldırmak mümkündür ancak önerilmez. documentName Yol parametresi uç nokta yolundan kaldırıldığında, çerçeve sorgu parametresinden belge adını çözümlemeye çalışır. yolunun veya sorgunun sağlanmaması documentName beklenmeyen davranışa neden olabilir.

OpenAPI uç noktasını özelleştirme

OpenAPI belgesi bir yol işleyicisi uç noktası aracılığıyla sunulduğundan, standart en düşük uç noktalarda kullanılabilen tüm özelleştirmeler OpenAPI uç noktası tarafından kullanılabilir.

Uç nokta meta verileriyle OpenAPI uç noktalarını özelleştirme

Aşağıdaki listede, oluşturulan OpenAPI belgesini özelleştirmek için kullanılan uç nokta meta verileri gösterilir:

Uç nokta meta verilerini değiştirerek oluşturulan OpenAPI belgesini özelleştirme hakkında daha fazla bilgi edinmek için bkz . OpenAPI'yi En Az API uygulamalarında kullanma.

OpenAPI belge erişimini yetkili kullanıcılarla sınırlama

OpenAPI uç noktası varsayılan olarak hiçbir yetkilendirme denetimini etkinleştirmez. Ancak, OpenAPI belgesine erişimi sınırlamak mümkündür. Örneğin, aşağıdaki kodda, OpenAPI belgesine erişim rolü olanlarla tester sınırlıdır:

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

Önbellekle oluşturulan OpenAPI belgesi

OpenAPI belgesi, OpenAPI uç noktasına her istek gönderildiğinde yeniden oluşturulur. Yeniden oluşturma, transformatörlerin dinamik uygulama durumunu çalışmalarına dahil etmelerini sağlar. Örneğin, isteği HTTP bağlamının ayrıntılarıyla yeniden oluşturma. Uygun olduğunda, her HTTP isteğinde belge oluşturma işlem hattının yürütülmesini önlemek için OpenAPI belgesi önbelleğe alınabilir.

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

OpenAPI belge dönüştürücüleri

Bu bölümde, OpenAPI belgelerinin transformatörlerle nasıl özelleştirileceği gösterilmektedir.

OpenAPI belgelerini transformatörlerle özelleştirme

Transformers, OpenAPI belgesini kullanıcı tanımlı özelleştirmelerle değiştirmek için bir API sağlar. Transformatörler aşağıdaki gibi senaryolar için kullanışlıdır:

  • Belgedeki tüm işlemlere parametre ekleme.
  • Parametreler veya işlemler için açıklamaları değiştirme.
  • OpenAPI belgesine üst düzey bilgiler ekleme.

Transformatörler iki kategoriye ayrılır:

  • Belge dönüştürücülerinin OpenAPI belgesinin tamamına erişimi vardır. Bunlar belgede genel değişiklikler yapmak için kullanılabilir.
  • İşlem transformatörleri her bir işlem için geçerlidir. Her bir işlem, yol ve HTTP yönteminin bir bileşimidir. Bunlar, uç noktalardaki parametreleri veya yanıtları değiştirmek için kullanılabilir.

Transformatörler, nesne üzerindeki çağrı OpenApiOptions aracılığıyla UseTransformer belgeye kaydedilebilir. Aşağıdaki kod parçacığında transformatörleri belgeye kaydetmenin farklı yolları gösterilmektedir:

  • Temsilci kullanarak bir belge transformatörü kaydedin.
  • örneğini kullanarak belge dönüştürücüsünün kaydını IOpenApiDocumentTransformeroluşturun.
  • DI-etkinleştirilmiş IOpenApiDocumentTransformerkullanarak bir belge transformatörü kaydedin.
  • Temsilci kullanarak bir işlem transformatörü kaydedin.
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();

Transformatörler için yürütme sırası

Transformatörler kayıt temelinde ilk sırada yürütülür. Aşağıdaki kod parçacığında, belge transformatörü işlem transformatörü tarafından yapılan değişikliklere erişime sahiptir:

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

Belge dönüştürücülerini kullanma

Belge dönüştürücülerinin aşağıdakiler içeren bir bağlam nesnesine erişimi vardır:

  • Değiştirilen belgenin adı.
  • Bu belgeyle ilişkili liste ApiDescriptionGroups .
  • IServiceProvider Belge oluşturmada kullanılan.

Belge dönüştürücüleri, oluşturulan OpenAPI belgesinin sesini de kapatabilir. Aşağıdaki örnekte, OpenAPI belgesine API hakkında bazı bilgiler ekleyen bir belge dönüştürücü gösterilmektedir.

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

Hizmet tarafından etkinleştirilen belge transformatörleri, uygulamayı değiştirmek için DI'den örnekleri kullanabilir. Aşağıdaki örnekte, kimlik doğrulama katmanından IAuthenticationSchemeProvider hizmeti kullanan bir belge dönüştürücü gösterilmektedir. JWT taşıyıcısı ile ilgili düzenlerin uygulamada kayıtlı olup olmadığını denetler ve bunları OpenAPI belgesinin en üst düzeyine ekler:

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

Belge dönüştürücüleri, ilişkilendirildikleri belge örneğine özeldir. Aşağıdaki örnekte bir transformatör:

  • Kimlik doğrulamasıyla ilgili gereksinimleri internal belgeye kaydeder.
  • Belgeyi public değiştirilmemiş olarak bırakır.
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>()
                });
            }
        }
    }
}

İşlem transformatörlerini kullanma

İşlemler, OpenAPI belgesindeki HTTP yollarının ve yöntemlerinin benzersiz birleşimleridir. İşlem transformatörleri, bir değişiklik yapıldığında yararlıdır:

  • Bir uygulamadaki her uç noktaya yapılmalıdır veya
  • Belirli yollara koşullu olarak uygulanır.

İşlem transformatörlerinin aşağıdakiler içeren bir bağlam nesnesine erişimi vardır:

  • İşlemin ait olduğu belgenin adı.
  • ApiDescription İşlemle ilişkili.
  • IServiceProvider Belge oluşturmada kullanılan.

Örneğin, aşağıdaki işlem transformatörü belgedeki tüm işlemler tarafından desteklenen bir yanıt durum kodu olarak ekler 500 .

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

Oluşturulan OpenAPI belgesini kullanma

OpenAPI belgeleri test, belge ve yerel geliştirme için mevcut araçlardan oluşan geniş bir ekosisteme bağlanabilir.

Yerel geçici test için Swagger kullanıcı arabirimini kullanma

Varsayılan olarak paket, Microsoft.AspNetCore.OpenApi OpenAPI belgesini görselleştirmek veya belgeyle etkileşime girmek için yerleşik destek sağlamaz. OpenAPI belgesini görselleştirmek veya belgeyle etkileşime açmak için kullanılan popüler araçlar arasında Swagger UI ve ReDoc yer alır. Swagger kullanıcı arabirimi ve ReDoc, bir uygulamada çeşitli yollarla tümleştirilebilir. Visual Studio ve VS Code gibi düzenleyiciler, OpenAPI belgelerinde test için uzantılar ve yerleşik deneyimler sunar.

Paket, Swashbuckle.AspNetCore.SwaggerUi uygulamalarda kullanılmak üzere Swagger kullanıcı arabiriminin web varlıklarından oluşan bir paket sağlar. Bu paket, oluşturulan belge için kullanıcı arabirimini işlemek için kullanılabilir. Bunu yapılandırmak için paketi yükleyin Swashbuckle.AspNetCore.SwaggerUi .

Swagger-ui ara yazılımını, daha önce kaydedilmiş OpenAPI yoluna bir başvuruyla etkinleştirin. Bilgilerin açığa çıkmasını ve güvenlik açığını sınırlamak için yalnızca geliştirme ortamlarında Swagger kullanıcı arabirimini etkinleştirin.

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

Etkileşimli API belgeleri için Skaler kullanma

Skaler , OpenAPI için açık kaynak etkileşimli bir belge kullanıcı arabirimidir. Skaler, ASP.NET Core tarafından sağlanan OpenAPI uç noktasıyla tümleştirilebilir. Scalar'ı yapılandırmak için paketi yükleyin Scalar.AspNetCore .

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

Spektral ile lint tarafından oluşturulan OpenAPI belgeleri

Spectral , açık kaynaklı bir OpenAPI belge linter'idir. Spektral, oluşturulan OpenAPI belgelerinin kalitesini doğrulamak için bir uygulama derlemesine eklenebilir. Spectral'i paket yükleme yol tariflerine göre yükleyin.

Spectral'den yararlanmak için derleme zamanı OpenAPI belge oluşturmayı etkinleştirmek için paketi yükleyin Microsoft.Extensions.ApiDescription.Server .

Uygulamanızın .csproj dosyasında aşağıdaki özellikleri ayarlayarak derleme zamanında belge oluşturmayı etkinleştirin":

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

Belgeyi oluşturmak için komutunu çalıştırın dotnet build .

dotnet build

Aşağıdaki içeriklere sahip bir .spectral.yml dosya oluşturun.

extends: ["spectral:oas"]

Oluşturulan dosyada komutunu çalıştırın spectral lint .

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)