-
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 etcarea-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesfeature-openapi
Milestone
Description
Background and Motivation
I was looking at how to wire up the servers
property based on the current HttpContext like NSwag does after opening #56188, and noticed that the HttpContext
isn't immediately available to any OpenAPI transformers.
It can be easily be made available via IHttpContextAccessor
, but that's often frowned upon from a performance perspective, so I figured it would be worth raising the possibility of making it available from the request pipeline to avoid the need to do that.
The HttpContext
could be passed through into OpenApiDocumentService.GetOpenApiDocumentAsync()
here:
var document = await documentService.GetOpenApiDocumentAsync(context.RequestAborted); |
Then it can be directly assigned into the various context objects passed to any transformers, as well as being available to the document service itself.
Proposed API
namespace Microsoft.AspNetCore.OpenApi;
public sealed partial class OpenApiDocumentTransformerContext
{
+ /// <summary>
+ /// Gets the HTTP context associated with the current HTTP request.
+ /// </summary>
+ public required HttpContext { get; init }
}
public sealed partial class OpenApiOperationTransformerContext
{
+ /// <summary>
+ /// Gets the HTTP context associated with the current HTTP request.
+ /// </summary>
+ public required HttpContext { get; init }
}
public sealed partial class OpenApiSchemaTransformerContext
{
+ /// <summary>
+ /// Gets the HTTP context associated with the current HTTP request.
+ /// </summary>
+ public required HttpContext { get; init }
}
Usage Examples
internal sealed class AddServersTransformer : IOpenApiDocumentTransformer
{
/// <inheritdoc/>
public Task TransformAsync(
OpenApiDocument document,
OpenApiDocumentTransformerContext context,
CancellationToken cancellationToken)
{
document.Servers = [new() { Url = GetServerUrl(context) }];
return Task.CompletedTask;
}
private static string GetServerUrl(OpenApiDocumentTransformerContext context)
{
var request = context.HttpContext.Request;
var scheme = TryGetFirstHeader("X-Forwarded-Proto") ?? request.Scheme;
var host = TryGetFirstHeader("X-Forwarded-Host") ?? request.Host.ToString();
return new Uri($"{scheme}://{host}").ToString().TrimEnd('/');
string? TryGetFirstHeader(string name)
=> request.Headers.TryGetValue(name, out var values) ? values.FirstOrDefault() : null;
}
}
Alternative Designs
None.
Risks
None?
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 etcarea-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesIncludes: MVC, Actions and Controllers, Localization, CORS, most templatesfeature-openapi