Epic: Minimal API - OpenAPI features
rafikiassumani-msft opened this issue · 3 comments
This issue covers the desired experience for minimal APIs integration with OpenAPI via metadata and ApiExplorer observing libraries like Swashbuckle and nSwag.
Issues (ASP.NET Core)
Priority One
Other
Issues (Swashbuckle)
- domaindrivendev/Swashbuckle.AspNetCore#2165
- domaindrivendev/Swashbuckle.AspNetCore#1691
- This issue covers the scenario but the work will involve updating Swashbuckle to properly respect the response types declared in the metadata (i.e. status code, content type(s), schema)
- Update default inclusion logic to consider any new metadata added to ASP.NET Core as part of #34068 regarding whether an endpoint should be excluded from document generation (example)
- PR for adding HostFactoryResolver to detect new app patterns domaindrivendev/Swashbuckle.AspNetCore#2147
- #34593 external issue on Swashbuckle
Additional context
The goal is to allow for minimal APIs to support having metadata specified (manually in .NET 6, either imperatively via extension methods or declaratively via attributes, potentially automatically based on endpoint implementation and/or convention in a release after .NET 6) that enables the following to be satisfied by default when an OpenAPI library is also configured (i.e. without the OpenAPI library requiring further manual configuration):
- Endpoint name that maps to
operationIdin generated OpenAPI documents.- Note the endpoint name is also used when using
LinkGeneratorto generate URL/links for endpoints
- Note the endpoint name is also used when using
- Endpoint group name that maps to the document name in generated OpenAPI documents (typically used for versioning, e.g. "v1", "v2")
- Metadata indicating that the API should be excluded/ignored from OpenAPI document generation
- Metadata indicating what response types a method produces, where each response is the combination of:
- One status code
- One or more content types, e.g. "application/json"
- An optional schema per content type
Examples
Example of what specifying the metadata imperatively could look like:
app.MapGet("/admin", () => "For admins only")
.WithName("AdminDetails")
.RequiresAuthorization("Admins")
.ExcludeFromApiExplorer();
app.MapPost("/todos", async (Todo todo, TodoDb db) =>
{
if (!MinimalValidation.TryValidate(todo, out var errors))
return Results.ValidationProblem(errors);
db.Todos.Add(todo);
await db.SaveChangesAsync();
return Results.CreatedAtRoute("GetTodoById", new { todo.Id }, todo);
})
.WithName("AddTodo")
.WithGroupName("v1")
.ProducesValidationProblem()
.Produces<Todo>(StatusCodes.Status201Created);Example of what specifying the metadata declaratively could look like:
app.MapGet("/admin", AdminDetails);
app.MapPost("/todos-attr-desc", AddTodo);
[Authorized(Policy = "Admins")]
[ExcludeFromApiExplorer]
string AdminDetails()
{
return "For admins only";
}
[EndpointGroupName("v1")]
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest, "application/problem+json")]
[ProducesResponseType(typeof(Todo), StatusCodes.Status201Created)]
async Task<IResult> AddTodo(Todo todo, TodoDb db)
{
if (!MinimalValidation.TryValidate(todo, out var errors))
return Results.ValidationProblem(errors);
db.Todos.Add(todo);
await db.SaveChangesAsync();
return Results.Created($"/todos/{todo.Id}", todo);
}I guess we need to understand how this affects MVC routes as well? I assume it will conflict. We need to figure out what happens when somebody does:
app.MapControlles().WithName("DontDoThis").ProducesValidationProblem();I am closing this issue as I moved the unfinished items to the following issue for .NET7 Planning: #37098