-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Adding API convention to contribute to Endpoint Metadata #41635
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
Adding API convention to contribute to Endpoint Metadata #41635
Conversation
responseTypeMetadataProviders, | ||
_modelMetadataProvider); | ||
|
||
var responseTypes = responseTypesFromProvider.Concat(responseTypesFromEndpointMetadata.Values).ToList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which metadata do we prefer? In the case of duplicates it looks like the last one wins so we should concat the preferred list in order to iterate over it last.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or, should we be removing duplicates? We do return this list and use it elsewhere, so I don't know the implications of duplicate items
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's additive. I think this is fine considering these are generally IResult
implementations, so I hope MVC isn't inferring any other response types by default.
aspnetcore/src/Mvc/Mvc.ApiExplorer/src/EndpointMetadataApiDescriptionProvider.cs
Line 341 in 8a4b4de
var producesResponseMetadata = endpointMetadata.GetOrderedMetadata<IProducesResponseTypeMetadata>(); |
Or, should we be removing duplicates?
To go off on a bit of a tangent, this got me thinking about how we have to be careful dealing with multiple pieces of Endpoint metadata of the same type going forward. We can no longer assume that conventions will be able to "see" duplicates because of the way route groups add metadata. Everything that wants to read additive metadata should be prepared for multiple pieces of metadata. This makes adding metadata easier, and I think more people are going to add metadata than read metadata.
See #41779 for an example of this. It's not really related to this PR but your comment got me thinking about this @BrennanConroy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that it is additive, however, thinking more about it, before my change we were not generating duplicates here.
results[apiResponseType.StatusCode] = apiResponseType; |
And I feel the right thing to do is processing in the following ordering:
- Process the metadata
- Process the attributes, overwriting any status code that we have set already (keep the users desired behavior)
@BrennanConroy @halter73 is that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to prefer attributes applied to the action directly over metadata provided by the response type given a conflict for a given status code. Hopefully this never happens in practice.
Closes #41421
This PR will introduce a new internal API Convention (
EndpointMetadataConvention
), included as default, that will discover metadata fromreturn type
orparameter types
that implementsIEndpointProviderMetadata
orIEndpointParameterProviderMetadata
and contribute toAction.Selectors
endpoint metadata.It also includes the following changes to APIExplorer:
IProducesResponseTypeMetadata
will contribute to theAPI Response types
metadata.IAcceptsMetadata
will contribute to theSupported Request Types
.These changes will affect only how the metadata is generated since the new metadata will not be added as a
Filter
.Example:
Metadata