-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Open
Labels
api-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementationarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-openapi
Milestone
Description
Background and Motivation
While working on #62193 (comment), I noticed that it isn't currently possible to dynamically select an OpenAPI document's version based on context provided by the user in an HTTP request, for example from a query string.
The version is currently defined in the options as part of registering the endpoint, so it isn't possible to change it other than when registering services, and as the options are registered as a singleton it isn't possible to mutate the options in the scope of an HTTP request to using something like IPostConfigureOptions<T>
to change its value before the document is written.
await document.SerializeAsync(openApiWriter, documentOptions.OpenApiVersion, context.RequestAborted); |
var options = endpoints.ServiceProvider.GetRequiredService<IOptionsMonitor<OpenApiOptions>>(); |
Proposed API
public OpenApiOptions
{
+ public Func<HttpContext, OpenApiSpecVersion?>? OpenApiVersionSelector { get; set; }
}
Then change the endpoint code to use it something like:
+ var openApiVersion = documentOptions.OpenApiVersionSelector?.Invoke(context) ?? documentOptions.OpenApiVersion;
- await document.SerializeAsync(openApiWriter, documentOptions.OpenApiVersion, context.RequestAborted);
+ await document.SerializeAsync(openApiWriter, openApiVersion, context.RequestAborted);
Usage Examples
builder.Services.AddOpenApi("v1", options =>
{
options.OpenApiVersionSelector = (context) =>
{
if (context.Request.Query["version"] is { Count: 1 } version &&
Enum.TryParse<OpenApiSpecVersion>(version, out var result))
{
return result;
}
return null;
};
});
GET /openapi/v1.json?version=OpenApi3_0
{
"openapi": "3.0.4"
}
Alternative Designs
public OpenApiOptions
{
+ public Func<HttpContext, Task<OpenApiSpecVersion?>>? OpenApiVersionSelector { get; set; }
}
Risks
None I can think of.
Metadata
Metadata
Assignees
Labels
api-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementationarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-openapi