-
Notifications
You must be signed in to change notification settings - Fork 10.3k
IOpenApiDocumentTransformer cannot modify components.Schemas since it's null #58406
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
@dnv-kimbell This is expected behavior. If you are trying to make schema-level customizations, the What are you trying to do? |
The reason why I started exploring this was to see if I could create a workaround for polymorphic types. I can't see how the information provided by the current Microsoft implementation can give me enough information to generate C# classes. There may also be other scenarios where one would want to look at the total list of schemas rather than each one individually. Based on the name of the transformer, it's not unreasonable to expect that you get a complete document, not just parts of it. Since this code is part of the yearly release schedule, we have to wait another year for any significant changes. If we had access to information, it would be possible for us to create workarounds until the Microsoft implementation is updated. |
I have the same problem. I wanted to change the name of the schemas. But I'm really looking for a way to influence the naming of the schemas, as like removing the suffix "Dto" from the type. That is important to me. |
Have you considered examining if the CreateSchemaReferenceId is a viable option for you? It allows influencing the name of reference IDs that are created for types (except the polymorphic one).
Out of curiosity, what information is missing for you here? |
I think I commented somewhere else, but I came up with this way after understanding that the annotation public static OpenApiOptions ApplySchemaNameTransforms(this OpenApiOptions options, Func<Type, string> transformer)
{
options.AddSchemaTransformer((schema, context, ct) =>
{
const string SchemaId = "x-schema-id";
if (schema.Annotations?.TryGetValue(SchemaId, out var referenceIdObject) == true
&& referenceIdObject is string newSchemaId)
{
var clrType = context.JsonTypeInfo.Type;
newSchemaId = transformer(clrType);
schema.Annotations[SchemaId] = newSchemaId;
}
return Task.CompletedTask;
});
return options;
} Polymorphic classes: Yes, changing name doesn't work for polymorphic classes since that is dealt by its own private set of transformer methods that are run by default after the transformers have run. Would be nice if those could become regular transformers, and that there would be transformers that allowed for inheritance, similar to what NSwag and Swashbuckle does by default. On the Transformers should be seen as middleware, if that makes sense. But the final composition stage happens after all the transformer have run. That is when similar schemas are being merged and placed in Schemas in OpenApiDocument. Because of what is mention above, it makes sense that at the transformer stage the "Components.Schemas" are not populated. But still confusing that the property is there if you, as a developer, don't understand this. Because you might expect that a Question: Should there be a way to hook into when a document has been fully composed? That would give you ability to do finishing touches. Even if risky. |
I have problems with this too. I want to remove some specific schemas that are generated by default. I can't use a schematransformer to remove a schema, and i can't edit the nulled list of schemas in the documenttransformer. |
I'm finding it quite frustrating trying to extend the default spec for this same reason mentioned here. I want to have an API endpoint that allows for partial model fields to be provided, which would be quite easy in other languages/frameworks. I've also found that the generated doc does not respect the configuration specified by |
It's a huge oversight that the |
Hi everyone! Doing some pruning on the backlog of OpenAPI issues and came across this one. I believe that we can close this out and dupe it to #60589. Some new APIs are being introduced in Microsoft.OpenApi v2 that make it a little bit easier to treat the document as a component store in third party APIs. This includes the introduction of methods like The code sample below shows how these APIs can be composed to support being able to dynamically insert schemas to things. Note, that in this model, you never interact with builder.Services.AddOpenApi("v1", options =>
{
options.AddOperationTransformer((operation, context, cancellationToken) =>
{
// Generate schema for error responses
var errorSchema = context.GetOrCreateSchema(typeof(ProblemDetails));
context.Document.AddComponent("Error", errorSchema);
// Reference the schema in responses
operation.Responses["500"] = new OpenApiResponse
{
Description = "Error",
Content =
{
["application/problem+json"] = new OpenApiMediaType
{
Schema = new OpenApiSchemaReference("Error", context.Document)
}
}
};
return Task.CompletedTask;
});
}); The proposed API above supports adding a |
How does this new api allow us to enumerate all the existing schemas in the document? Some things can be done in a schema/operation transformer, but some things are easier to do when you have access to the totality. This might be an edge case, but when you have something called an |
In the new model, you do have access to the all the schemas in the document since they are inserted into the document as they are constructed instead of via a document transformer as the final step (as in the current model). The following code: using System.Diagnostics;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenApi(options =>
{
options.AddDocumentTransformer((document, context, ct) =>
{
Debug.Assert(document.Components != null, "Components should not be null");
Debug.Assert(document.Components.Schemas != null, "Schemas should not be null");
foreach (var schema in document.Components.Schemas)
{
Console.WriteLine(schema.Key);
}
return Task.CompletedTask;
});
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.MapPost("/weather", (WeatherForecast forecast) => { });
app.MapPost("/todo", (Todo todo) => { });
app.MapPost("/user", (User user) => { });
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary);
record Todo(int Id, string Title, bool Completed);
record User(int Id, string Name, string Email); will write the following to the console:
|
Unfortunately that code sample isn't working for me - document.Components is always null in the document transformer. In my case I have an OData endpoint which causes the Open API document to include a bunch of objects not really relevant to the API end users: Using Swashbuckle.AspNetCore.SwaggerGen I am able to remove schemas from the final open API document using the IDocumentFilter interface and the document.Components.Schemas.Remove() method in code similar to this: I am not seeing any way to remove schemas in the new Microsoft.AspNetCore.OpenApi IOpenApiDocumentTransformer since the Components object is always null on the document: Is there any way to remove or update schemas similar to how we currently can using the SwaggerGen package? |
To clarify, the code sample only works for .NET 10 because we take a dependency on some API changes in Microsoft.OpenApi v2. This isn't feasible in .NET 9 and we likely won't be making any retroactive changes to support it. |
You can use this middleware to modify the response on the way out. In this example I'm removing well-known types that I don't want in the response. They key part is loading it into the
|
Since this is funny so I decided to keep it on:
It fulfills all the collections I need so now I can freely remove properties from openapi docs. Yes this is silly but it's working better than the variation above. |
Is there an existing issue for this?
Describe the bug
When running
IOpenApiDocumentTransformer
, it would be logical to have the ability to modify theOpenApiDocument.Components.Schemas
to make any adjustments. TheOpenApiDocument.Components
is null.aspnetcore/src/OpenApi/src/Services/OpenApiDocumentService.cs
Lines 100 to 106 in 049814c
The
await _schemaReferenceTransformer.TransformAsync(document, documentTransformerContext, cancellationToken)
populates theComponents.Schemas
, but that happens after the document transformers are run.Expected Behavior
It should be possible to modify Components.Schemas in the
IOpenApiDocumentTransformer
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
.NET 9 RC2
Anything else?
No response
The text was updated successfully, but these errors were encountered: