OpenAPI 문서 생성
이 패키지는 Microsoft.AspNetCore.OpenApi
ASP.NET Core에서 OpenAPI 문서 생성을 기본적으로 지원합니다. 패키지는 다음과 같은 기능을 제공합니다.
- 런타임에 OpenAPI 문서를 생성하고 앱의 엔드포인트를 통해 액세스할 수 있도록 지원합니다.
- 생성된 문서를 수정할 수 있는 "변환기" API를 지원합니다.
- 단일 앱에서 여러 OpenAPI 문서 생성을 지원합니다.
- 에서 제공하는
System.Text.Json
JSON 스키마 지원을 활용합니다. - 네이티브 AoT와 호환됩니다.
패키지 설치
Microsoft.AspNetCore.OpenApi
패키지를 설치합니다.
패키지 관리자 콘솔에서 다음 명령을 실행합니다.
Install-Package Microsoft.AspNetCore.OpenApi
OpenAPI 문서 생성 구성
코드는 다음과 같습니다.
- 앱 작성기 서비스 컬렉션에서 AddOpenApi 확장 메서드를 사용하여 OpenAPI 서비스를 추가합니다.
- 앱의 MapOpenApi 확장 메서드를 사용하여 OpenAPI 문서를 JSON 형식으로 보기 위한 엔드포인트를 매핑합니다.
var builder = WebApplication.CreateBuilder();
builder.Services.AddOpenApi();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.MapGet("/", () => "Hello world!");
app.Run();
앱을 시작하고 생성된 OpenAPI 문서를 보려면 이동합니다 https://localhost:<port>/openapi/v1.json
.
OpenAPI 문서 생성을 사용자 지정하는 옵션
다음 섹션에서는 OpenAPI 문서 생성을 사용자 지정하는 방법을 보여 줍니다.
OpenAPI 문서 이름 사용자 지정
앱의 각 OpenAPI 문서에는 고유한 이름이 있습니다. 등록된 기본 문서 이름은 .입니다 v1
.
builder.Services.AddOpenApi(); // Document name is v1
AddOpenApi 호출에 이름을 매개 변수로 전달하여 문서 이름을 수정할 수 있습니다.
builder.Services.AddOpenApi("internal"); // Document name is internal
문서 이름은 OpenAPI 구현의 여러 위치에 표시됩니다.
생성된 OpenAPI 문서를 가져올 때 문서 이름은 요청에서 documentName
매개 변수 인수로 제공됩니다. 다음 요청은 v1
및 internal
문서를 해결합니다.
GET http://localhost:5000/openapi/v1.json
GET http://localhost:5000/openapi/internal.json
생성된 문서의 OpenAPI 버전 사용자 지정
기본적으로 OpenAPI 문서 생성은 OpenAPI 사양의 v3.0을 준수하는 문서를 만듭니다. 다음 코드는 OpenAPI 문서의 기본 버전을 수정하는 방법을 보여 줍니다.
builder.Services.AddOpenApi(options =>
{
options.OpenApiVersion = OpenApiSpecVersion.OpenApi2_0;
});
OpenAPI 엔드포인트 경로 사용자 지정
기본적으로 MapOpenApi 호출을 통해 등록된 OpenAPI 엔드포인트는 /openapi/{documentName}.json
엔드포인트에서 문서를 제공합니다. 다음 코드는 OpenAPI 문서가 등록된 경로를 사용자 지정하는 방법을 보여 줍니다.
app.MapOpenApi("/openapi/{documentName}/openapi.json");
엔드포인트 경로에서 경로 매개 변수를 documentName
제거할 수는 있지만 권장되지는 않습니다. 경로 매개 변수가 documentName
엔드포인트 경로에서 제거되면 프레임워크는 쿼리 매개 변수에서 문서 이름을 확인하려고 시도합니다. 경로 또는 쿼리에 제공하지 documentName
않으면 예기치 않은 동작이 발생할 수 있습니다.
OpenAPI 엔드포인트 사용자 지정
OpenAPI 문서는 경로 처리기 엔드포인트를 통해 제공되므로 표준 최소 엔드포인트에서 사용할 수 있는 모든 사용자 지정을 OpenAPI 엔드포인트에서 사용할 수 있습니다.
OpenAPI 문서 액세스를 권한 있는 사용자로 제한
OpenAPI 엔드포인트는 기본적으로 권한 부여 검사를 사용하도록 설정하지 않습니다. 그러나 권한 부여 검사는 OpenAPI 문서에 적용할 수 있습니다. 다음 코드에서 OpenAPI 문서에 대한 액세스는 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();
생성된 OpenAPI 문서 캐시
OpenAPI 엔드포인트에 대한 요청이 전송될 때마다 OpenAPI 문서가 다시 생성됩니다. 재생 기능은 변환기가 동적 앱 상태를 작업에 통합할 수 있게 합니다. 예를 들어 HTTP 컨텍스트의 세부 정보를 사용하여 요청을 다시 생성합니다. 해당하는 경우 각 HTTP 요청에서 문서 생성 파이프라인을 실행하지 않도록 OpenAPI 문서를 캐시할 수 있습니다.
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();
여러 OpenAPI 문서 생성
일부 시나리오에서는 단일 ASP.NET Core API 앱에서 다양한 콘텐츠를 사용하여 여러 개의 OpenAPI 문서를 생성하는 것이 유용할 수 있습니다. 이 시나리오에는 다음이 포함됩니다.
- 공용 및 내부 API와 같은 다양한 대상 그룹에 대한 OpenAPI 설명서 생성
- 다양한 버전의 API에 대한 OpenAPI 설명서 생성
- 프런트 엔드 및 백 엔드 API와 같은 앱의 여러 부분에 대한 OpenAPI 설명서 생성
여러 OpenAPI 문서를 생성하려면 각 문서에 대해 AddOpenApi 확장 메서드를 한 번 호출하고 매번 첫 번째 매개 변수에 다른 문서 이름을 지정합니다.
builder.Services.AddOpenApi("v1");
builder.Services.AddOpenApi("v2");
각 AddOpenApi 호출은 고유한 옵션 집합을 지정할 수 있으므로 각 OpenAPI 문서에 대해 동일하거나 다른 사용자 지정을 사용하도록 선택할 수 있습니다.
프레임워크는 ShouldInclude의 OpenApiOptions 대리자 메서드를 사용하여 각 문서에 포함할 엔드포인트를 결정합니다.
각 문서에 대해 앱의 각 엔드포인트에 대해 ShouldInclude 대리자 메서드가 호출되어 엔드포인트에 대한 ApiDescription 개체를 전달합니다. 이 메서드는 엔드포인트를 문서에 포함해야 하는지 여부를 나타내는 부울 값을 반환합니다. ApiDescription 개체:
- 에는 HTTP 메서드, 경로 및 응답 형식과 같은 엔드포인트에 대한 정보가 포함되어 있습니다.
- 특성 또는 확장 메서드를 통해 엔드포인트에 연결된 메타데이터입니다.
이 대리자의 기본 구현에서는 GroupName의 ApiDescription 필드를 사용합니다. 대리자는 WithGroupName 확장 메서드 또는 EndpointGroupNameAttribute 특성을 사용하여 엔드포인트에서 설정됩니다.
WithGroupName
또는 EndpointGroupName
특성은 문서에 포함할 엔드포인트를 결정합니다. 그룹 이름이 할당되지 않은 모든 엔드포인트는 모든 OpenAPI 문서에 포함됩니다.
// Include endpoints without a group name or with a group name that matches the document name
ShouldInclude = (description) => description.GroupName == null || description.GroupName == DocumentName;
선택한 조건에 따라 엔드포인트를 포함하거나 제외하도록 ShouldInclude 대리자 메서드를 사용자 지정할 수 있습니다.
빌드 시 OpenAPI 문서 생성
일반적인 웹앱에서 OpenAPI 문서는 런타임에 생성되고 앱 서버에 대한 HTTP 요청을 통해 제공됩니다.
일부 시나리오에서는 앱의 빌드 단계에서 OpenAPI 문서를 생성하는 것이 유용합니다. 이 시나리오에는 다음이 포함됩니다.
- 소스 제어에 커밋된 OpenAPI 설명서 생성
- 사양 기반 통합 테스트에 사용되는 OpenAPI 설명서 생성
- 웹 서버에서 정적으로 제공되는 OpenAPI 설명서 생성
빌드 시 OpenAPI 문서 생성에 대한 지원을 추가하려면 패키지를 설치합니다 Microsoft.Extensions.ApiDescription.Server
.
패키지 관리자 콘솔에서 다음 명령을 실행합니다.
Install-Package Microsoft.Extensions.ApiDescription.Server
설치 시 이 패키지는 다음과 같습니다.
- 빌드하는 동안 앱과 연결된 Open API 문서를 자동으로 생성합니다.
- 앱의 출력 디렉터리에서 Open API 문서를 채웁니다.
여러 문서가 등록되면 및 문서 이름은v1
문서 이름이 후에 추가됩니다. 예: {ProjectName}_{DocumentName}.json
.
dotnet build
type obj\{ProjectName}.json
빌드 시 문서 생성을 맞춤 설정하기
생성된 Open API 파일의 출력 디렉터리 수정
기본적으로 생성된 OpenAPI 문서는 앱의 출력 디렉터리로 내보내됩니다. 내보낸 파일의 위치를 수정하려면 속성에서 OpenApiDocumentsDirectory
대상 경로를 설정합니다.
<PropertyGroup>
<OpenApiDocumentsDirectory>.</OpenApiDocumentsDirectory>
</PropertyGroup>
OpenApiDocumentsDirectory
값은 프로젝트 파일을 기준으로 확인됩니다.
.
위의 값을 사용하면 프로젝트 파일과 동일한 디렉터리에 OpenAPI 문서가 내보내됩니다.
출력 파일 이름 수정
기본적으로 생성된 OpenAPI 문서는 앱의 프로젝트 파일과 동일한 이름을 갖습니다. 내보낸 파일의 이름을 수정하려면 속성에서 --file-name
인수를 OpenApiGenerateDocumentsOptions
설정합니다.
<PropertyGroup>
<OpenApiGenerateDocumentsOptions>--file-name my-open-api</OpenApiGenerateDocumentsOptions>
</PropertyGroup>
생성할 OpenAPI 문서 선택
일부 앱은 여러 OpenAPI 문서를 내보내도록 구성할 수 있습니다. 여러 버전의 API에 대해 여러 OpenAPI 문서를 생성하거나 공용 및 내부 API를 구분할 수 있습니다. 기본적으로 빌드 시간 문서 생성기는 앱에 구성된 모든 문서에 대한 파일을 내보냅니다. 단일 문서 이름에 대해서만 내보내려면 속성에서 --document-name
인수를 OpenApiGenerateDocumentsOptions
설정합니다.
<PropertyGroup>
<OpenApiGenerateDocumentsOptions>--document-name v2</OpenApiGenerateDocumentsOptions>
</PropertyGroup>
빌드 시간 문서 생성 중 런타임 동작 사용자 지정
모의 서버 구현을 사용하여 앱의 진입점을 실행함으로써 빌드 시 OpenAPI 문서 생성 기능을 수행합니다. OpenAPI 문서의 모든 정보를 정적으로 분석할 수 없으므로 정확한 OpenAPI 문서를 생성하려면 모의 서버가 필요합니다. 앱 진입점이 호출되므로 앱 시작의 모든 논리가 호출됩니다. 여기에는 서비스를 DI 컨테이너에 주입하거나 구성을 읽는 코드가 포함됩니다. 일부 시나리오에서는 빌드 시간 문서 생성에서 앱 진입점을 호출할 때 실행되는 코드 경로를 제한해야 합니다. 이 시나리오에는 다음이 포함됩니다.
- 특정 구성 문자열에서 읽지 않습니다.
- 데이터베이스 관련 서비스를 등록하지 않습니다.
이러한 코드 경로가 빌드 시간 생성 파이프라인에서 호출되지 않도록 제한하기 위해, 엔트리 어셈블리에 대한 검사를 통해 조건을 설정할 수 있습니다.
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 서비스 검색, 복원력, 상태 검사 및 OpenTelemetry와 같은 일반적인 .NET Aspire 서비스를 추가합니다.
트리밍 및 네이티브 사전 컴파일(AOT)
ASP.NET Core의 OpenAPI는 트리밍 및 네이티브 AOT를 지원합니다. 다음 단계에서는 트리밍 및 네이티브 AOT를 사용하여 OpenAPI 앱을 생성 및 게시합니다.
새 ASP.NET Core Web API(네이티브 AOT) 프로젝트를 만듭니다.
dotnet new webapiaot
Microsoft.AspNetCore.OpenAPI 패키지를 추가합니다.
dotnet add package Microsoft.AspNetCore.OpenApi
OpenAPI 문서를 생성할 수 있도록 Program.cs
업데이트합니다.
+ builder.Services.AddOpenApi();
var app = builder.Build();
+ app.MapOpenApi();
앱을 게시합니다.
dotnet publish
최소 API는 Microsoft.AspNetCore.OpenApi
패키지를 통해 앱의 엔드포인트에 대한 정보를 생성하기 위한 기본 제공 지원을 제공합니다. 시각적 UI를 통해 생성된 OpenAPI 정의를 노출하려면 타사 패키지가 필요합니다. 컨트롤러 기반 API에서 OpenAPI 지원에 대한 자세한 내용은 이 문서의 .NET 9 버전을 참조 하세요.
다음 코드는 ASP.NET Core 최소 웹 API 템플릿에서 생성되며 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);
}
앞의 강조 표시된 코드에서 다음을 수행합니다.
-
Microsoft.AspNetCore.OpenApi
는 다음 섹션에 설명되어 있습니다. -
AddEndpointsApiExplorer : API 탐색기를 사용하여 기본 주석이 있는 엔드포인트를 검색하고 설명하도록 앱을 구성합니다.
WithOpenApi
는 API 탐색기에서 생성된 일치하는 기본 주석을Microsoft.AspNetCore.OpenApi
패키지에서 생성된 주석으로 덮어씁니다. -
UseSwagger
는 Swagger 미들웨어를 추가합니다. - 'UseSwaggerUI'를 사용하면 포함된 버전의 Swagger UI 도구를 사용할 수 있습니다.
- WithName: 엔드포인트의 IEndpointNameMetadata는 링크 생성에 사용되며 지정된 엔드포인트의 OpenAPI 사양에서 작업 ID로 처리됩니다.
-
WithOpenApi
는 이 문서 뒷부분에 설명되어 있습니다.
Microsoft.AspNetCore.OpenApi
NuGet 패키지
ASP.NET Core는 엔드포인트에 대한 OpenAPI 사양과 상호 작용하는 Microsoft.AspNetCore.OpenApi
패키지를 제공합니다. 이 패키지는 Microsoft.AspNetCore.OpenApi
패키지에 정의된 OpenAPI 모델과 최소 API에 정의된 엔드포인트 간의 링크 역할을 합니다. 이 패키지는 엔드포인트의 매개 변수, 응답 및 메타데이터를 검사하여 엔드포인트를 설명하는 데 사용되는 OpenAPI 주석 형식을 생성하는 API를 제공합니다.
Microsoft.AspNetCore.OpenApi
는 프로젝트 파일에 PackageReference로 추가됩니다.
<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>
Swashbuckle.AspNetCore
, Microsoft.AspNetCore.OpenApi
와 함께 Swashbuckle.AspNetCore
를 사용할 때 6.4.0 이상을 사용해야 합니다.
Microsoft.OpenApi
호출에서 복사 생성자를 활용하려면 WithOpenApi
1.4.3 이상을 사용해야 합니다.
WithOpenApi
를 통해 엔드포인트에 OpenAPI 주석 추가
엔드포인트에서 WithOpenApi
를 호출하면 엔드포인트의 메타데이터가 추가됩니다. 이 메타데이터는 다음과 같습니다.
- Swashbuckle.AspNetCore와 같은 타사 패키지에서 소비됩니다.
- Swagger 사용자 인터페이스 또는 API를 정의하기 위해 생성된 YAML 또는 JSON에 표시됩니다.
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();
WithOpenApi
에서 OpenAPI 주석 수정
WithOpenApi
메서드는 OpenAPI 주석을 수정하는 데 사용할 수 있는 함수를 허용합니다. 예를 들어 다음 코드에서는 엔드포인트의 첫 번째 매개 변수에 설명이 추가됩니다.
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;
});
OpenAPI에 작업 ID 추가
작업 ID는 OpenAPI에서 지정된 엔드포인트를 고유하게 식별하는 데 사용됩니다.
WithName
확장 메서드를 사용하여 메서드에 사용되는 작업 ID를 설정할 수 있습니다.
app.MapGet("/todoitems2", async (TodoDb db) =>
await db.Todos.ToListAsync())
.WithName("GetToDoItems");
또는 OpenAPI 주석에서 직접 OperationId
속성을 설정할 수 있습니다.
app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
.WithOpenApi(operation => new(operation)
{
OperationId = "GetTodos"
});
OpenAPI 설명에 태그 추가
OpenAPI는 태그 개체 를 사용하여 작업을 분류할 수 있도록 지원합니다. 이러한 태그는 일반적으로 Swagger UI에서 작업을 그룹화하는 데 사용됩니다. 이러한 태그는 원하는 태그를 사용하여 엔드포인트에서 WithTags 확장 메서드를 호출하여 작업에 추가할 수 있습니다.
app.MapGet("/todoitems", async (TodoDb db) =>
await db.Todos.ToListAsync())
.WithTags("TodoGroup");
또는 OpenApiTags
확장 메서드를 통해 OpenAPI 주석에서 WithOpenApi
목록을 설정할 수 있습니다.
app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
.WithOpenApi(operation => new(operation)
{
Tags = new List<OpenApiTag> { new() { Name = "Todos" } }
});
엔드포인트 요약 또는 설명 추가
WithOpenApi
확장 메서드를 호출하여 엔드포인트 요약 및 설명을 추가할 수 있습니다. 다음 코드에서 요약은 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"
});
OpenAPI 설명 제외
다음 샘플에서 /skipme
엔드포인트는 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();
API를 사용되지 않는 것으로 표시
엔드포인트를 사용되지 않는 것으로 표시하려면 OpenAPI 주석에서 Deprecated
속성을 설정합니다.
app.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
.WithOpenApi(operation => new(operation)
{
Deprecated = true
});
응답 형식 설명
OpenAPI는 API에서 반환된 응답에 대한 설명을 제공할 수 있습니다. 최소 API는 엔드포인트의 응답 유형을 설정하기 위한 세 가지 전략을 지원합니다.
- 엔드포인트의
Produces
확장 메서드 사용 - 경로 처리기의
ProducesResponseType
특성 사용 - 경로 처리기에서
TypedResults
를 반환함으로써
Produces
확장 메서드를 사용하여 엔드포인트에 Produces
메타데이터를 추가할 수 있습니다. 매개 변수가 제공되지 않으면 확장 메서드는 200
상태 코드 및 application/json
콘텐츠 형식에서 대상 형식에 대한 메타데이터를 채웁니다.
app
.MapGet("/todos", async (TodoDb db) => await db.Todos.ToListAsync())
.Produces<IList<Todo>>();
엔드포인트의 경로 처리기 구현에서 TypedResults
를 사용하면 엔드포인트에 대한 응답 형식 메타데이터가 자동으로 포함됩니다. 예를 들어, 다음 코드는 200
콘텐츠 형식의 application/json
상태 코드 아래에 응답으로 엔드포인트에 자동으로 주석을 추가합니다.
app.MapGet("/todos", async (TodoDb db) =>
{
var todos = await db.Todos.ToListAsync());
return TypedResults.Ok(todos);
});
ProblemDetails
에 대한 응답 설정
엔드포인트가 ProblemDetails 응답을 반환할 수 있는 경우, 해당 엔드포인트의 메타데이터에 적절한 주석을 추가하기 위해 ProducesProblem 확장 메서드, ProducesValidationProblem, 또는 TypedResults.Problem
를 사용하여 응답 유형을 설정할 수 있습니다.
ProducesProblem
및 ProducesValidationProblem
확장 메서드는 .NET 8 이하의 경로 그룹에서 사용할 수 없습니다.
위의 전략 중 하나에서 제공하는 명시적 주석이 없는 경우, 프레임워크는 응답의 서명을 검사하여 기본 응답 유형을 확인하려고 시도합니다. 이 기본 응답은 OpenAPI 정의의 200
상태 코드 아래에 채워집니다.
여러 응답 유형
엔드포인트가 다양한 시나리오에서 다른 응답 형식을 반환할 수 있는 경우 다음과 같은 방법으로 메타데이터를 제공할 수 있습니다.
다음 예제와 같이
Produces
확장 메서드를 여러 번 호출합니다.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);
다음 예제와 같이, 서명에
Results<TResult1,TResult2,TResultN>
을 사용하고 처리기 본문에TypedResults
를 사용합니다.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>
공용 유형은 경로 처리기가 여러IResult
을(를) 구현하는 구체적인 형식을 반환하고, 그들 중에서IEndpointMetadataProvider
을(를) 구현하는 형식이 있다면 엔드포인트의 메타데이터에 기여한다고 선언합니다.유니언 형식은 암시적 캐스트 연산자를 구현합니다. 이러한 연산자를 사용하면 컴파일러가 제네릭 인수에 지정된 형식을 공용 구조체 형식의 인스턴스로 자동으로 변환할 수 있습니다. 이 기능은 경로 처리기가 선언한 결과만 반환한다는 컴파일 타임 검사를 제공하는 추가 이점이 있습니다. 제네릭 인수 중 하나로 선언되지 않은 형식을
Results<TResult1,TResult2,TResultN>
로 반환하려고 시도하면 컴파일 오류가 발생합니다.
요청 본문 및 매개 변수 설명
OpenAPI는 엔드포인트에서 반환되는 형식을 설명하는 것 외에도 API에서 사용하는 입력에 주석을 추가하는 것도 지원합니다. 이러한 입력은 다음 두 가지 범주로 분류됩니다.
- 경로, 쿼리 문자열, 헤더 또는 쿠키에 표시되는 매개 변수
- 요청 본문의 일부로 전송되는 데이터
프레임워크는 경로 처리기의 서명에 따라 경로, 쿼리 및 헤더 문자열의 요청 매개 변수 형식을 자동으로 유추합니다.
요청 본문으로 전송되는 입력 유형을 정의하려면 Accepts
확장 메서드를 사용하여 요청 처리기에서 예상하는 개체 형식 및 콘텐츠 형식을 정의하여 속성을 구성합니다. 다음 예제에서 엔드포인트는 요청 본문에 예상되는 콘텐츠 형식이 Todo
인 application/xml
개체를 허용합니다.
app.MapPost("/todos/{id}", (int id, Todo todo) => ...)
.Accepts<Todo>("application/xml");
Accepts
확장 메서드 외에도 매개 변수 형식은 IEndpointParameterMetadataProvider
인터페이스를 구현하여 자체 주석을 설명할 수 있습니다. 예를 들어, 다음 Todo
형식은 application/xml
콘텐츠 형식의 요청 본문이 필요한 주석을 추가합니다.
public class Todo : IEndpointParameterMetadataProvider
{
public static void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder)
{
builder.Metadata.Add(new ConsumesAttribute(typeof(Todo), isOptional: false, "application/xml"));
}
}
명시적 주석이 제공되지 않으면 프레임워크는 엔드포인트 처리기에 요청 본문 매개 변수가 있는 경우 기본 요청 유형을 확인하려고 시도합니다. 유추는 다음 추론을 사용하여 주석을 생성합니다.
-
[FromForm]
특성을 통해 양식에서 읽은 요청 본문 매개 변수는multipart/form-data
콘텐츠 형식으로 설명됩니다. - 다른 모든 요청 본문 매개 변수는
application/json
콘텐츠 형식으로 설명됩니다. - 요청 본문은 nullable이거나
AllowEmpty
속성이FromBody
특성에 설정된 경우 선택 사항으로 처리됩니다.
API 버전 관리 지원
최소 API는 Asp.Versioning.Http 패키지를 통해 API 버전 관리를 지원합니다. 최소 API를 사용하여 버전 관리를 구성하는 예제는 API 버전 관리 리포지토리에서 찾을 수 있습니다.
GitHub의 ASP.NET Core OpenAPI 소스 코드
추가 리소스
최소 API 앱은 Swashbuckle을 사용하는 경로 처리기에 대한 OpenAPI 사양을 설명할 수 있습니다.
컨트롤러 기반 API에서 OpenAPI 지원에 대한 자세한 내용은 이 문서의 .NET 9 버전을 참조 하세요.
다음 코드는 OpenAPI를 지원하는 일반적인 ASP.NET Core 앱입니다.
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 설명 제외
다음 샘플에서 /skipme
엔드포인트는 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();
응답 형식 설명
다음 예는 기본 제공 결과 형식을 사용하여 응답을 사용자 지정합니다.
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);
OpenAPI에 작업 ID 추가
app.MapGet("/todoitems2", async (TodoDb db) =>
await db.Todos.ToListAsync())
.WithName("GetToDoItems");
OpenAPI 설명에 태그 추가
다음 코드는 OpenAPI 그룹화 태그를 사용합니다.
app.MapGet("/todoitems", async (TodoDb db) =>
await db.Todos.ToListAsync())
.WithTags("TodoGroup");
ASP.NET Core