-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Support options for setting callback used to generated reference IDs in OpenAPI #56305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@captainsafia In my api's I like to nest the request / responses objects within the class containing the endpoint mapping as well as the implementation. var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapOpenApi();
CreateArticle.MapEndpoint(app);
UpdateArticle.MapEndpoint(app);
app.Run();
public class CreateArticle
{
public static RouteHandlerBuilder MapEndpoint(IEndpointRouteBuilder endpoints) =>
endpoints.MapPost("/articles", async (Request request) => { });
public record Request(string title);
}
public class UpdateArticle
{
public static RouteHandlerBuilder MapEndpoint(IEndpointRouteBuilder endpoints) =>
endpoints.MapPost("/articles/{id}", async (string id, Request request) => { });
public record Request(string title, string description);
} However this results in schema's named Would this feature allow me to generate ids like |
Oh! I really like this organization structure.
Yes -- it would! I'm actually hoping to take this API through review (ref) tomorrow. Do you have any thoughts on the shape I am currently proposing for it that we should consider as part of the review? |
Awesome @captainsafia, your initial suggestion makes the most sense to me public Func<Type, OpenApiSchema, string> CreateReferenceId { get; set; } |
@michael-wolfenden I ended up making a few changes to the API ahead of today's API review after I started implementing it. You should still be able to achieve the desired result but the shape is a little different now. |
[API Review]
CreateSchemaReferenceId = (type) => {
- if (type ...)
- return type.FullName;
- else
- return OpenApiOptions.CreateDefaultSchemaReferenceId(type);
}
namespace Microsoft.AspNetCore.OpenApi;
public sealed class OpenApiOptions
{
+ public static string? CreateDefaultSchemaReferenceId(JsonTypeInfo jsonTypeInfo);
+ public Func<JsonTypeInfo, string?> CreateSchemaReferenceId { get; set; }
} API Approved! |
This looks great. Though I find returning Would this also enable to specify the name of the discriminator property? I'm asking because we have a use case where it must be one of the model properties (the JSON:API spec we implement requires this). Example: "dataInResponse": {
"required": [
"type"
],
"type": "object",
"properties": {
"type": {
"minLength": 1,
"type": "string"
}
},
"additionalProperties": false,
"discriminator": {
"propertyName": "type",
"mapping": {
"people": "#/components/schemas/personDataInResponse",
"tags": "#/components/schemas/tagDataInResponse",
"todoItems": "#/components/schemas/todoItemDataInResponse"
}
},
"x-abstract": true
} In the example above, we must ensure that:
For completeness, one of the derived types looks like this (I've left out extra properties in both snippets for brevity): "personDataInResponse": {
"allOf": [
{
"$ref": "#/components/schemas/dataInResponse"
},
{
"required": [
"id"
],
"type": "object",
"properties": {
"id": {
"minLength": 1,
"type": "string"
}
},
"additionalProperties": false
}
],
"additionalProperties": false
}, |
It can be helpful if the user wishes to override the framework defaults around inlined schemas (e.g. we currently capture dictionary and array types by reference).
The values of If you're system builds on top of System.Text.Json's polymorphism attributes, then you should be good to go here.
Yes, the API proposed here would impact the references that are used in the response in particular. For our implementation, we're opinionated about the unique reference IDs for polymorphic schemas being |
Thanks for the clarifications. |
Background and Motivation
The OpenAPI implementation generates reference IDs for schemas that are duplicated across the OpenAPI document. By default, a unique identifier is generated for the schema using a combination of the schema itself and the type associated with the schema. At times, it might be necessary for users to override our default behavior with their own reference ID generation function.
Proposed API
namespace Microsoft.AspNetCore.OpenApi; public sealed class OpenApiOptions { + public Func<JsonTypeInfo, string?> CreateSchemaReferenceId { get; set; } }
Usage Examples
Alternative Designs
Instead of specifying custom schema IDs via a callback, we could support a custom attribute on types that would allow users to set reference IDs for the types they care about. For example:
Risks
Exposing an option for customizing the way reference IDs are created adds additional burden onto the user to ensure that the callback they provide will generate unique and accurate reference IDs for all the types that are used in their application.
The text was updated successfully, but these errors were encountered: