Add a source generator to generate versioned DTOs #1466
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In working on a new version of an API endpoint I've run into issues with API model duplication. Amending a type in the new version that's re-used across multiple endpoints requires redefining every controller action, request, response and API model type that is in the dependency graph to keep schema generation happy - this is too much pain.
This PR resurrects and tidies up an old source generation POC I did some time ago. With it you can annotate a type with
[GenerateVersionedDto(<some type>)]
and a partial declaration will be generated with all the members of the referenced type. Other referenced types will be generated recursively. This means you can have a stub type like:and all the members from
SomeOldVersion.Responses.GetPersonResponse
will be cloned onto anotherpartial record GetPersonResponse
along with all the types thatSomeOldVersion.Responses.GetPersonResponse
references. This makes it significantly easier to add new API versions that tweak existing response schema.In future I'd like to amend the source generator to be an incremental source generator but in the interests of time I've not done that here.
The first commit here is the source generator itself and the second makes the necessary changes to use it. I've also removed some re-use of request/response types across versions; each endpoint should use request and response types from its version only.