docs icon indicating copy to clipboard operation
docs copied to clipboard

System.Text.Json SourceGenerator should have better docs and public API

Open piskov opened this issue 1 year ago • 7 comments

(I apologize in advance if this is the wrong place for such kind of feedback. If so, would appreciate any advice where to put this)

Docs issue

The following two links are basically the only docs on JSON source generators:

The issue is that they describe one simple class consisting of basic .net types (e. g. integers or bools) that is nowhere near the real-world usage. Web APIs have a lot of DTOs (data transfer objects) which are used in multiple ways in controllers (get, put, etc.) and can be nested.

Here are just a handful of questions that are not answered in docs:

  1. Suppose one has dozens (or hundreds) DTOs in Web API. How one should add source gen for them? One context with dozens (hunderds) of attributes for each DTO? Separate contexts? Should I have source gen for all DTOs or only some?

    It would be great to see an example with at least 2-3 DTOs, not a single WeatherForecast. And guidelines/tips how to add source generation for the entire API with dozens (hundreds) of DTOs.

  2. What to do with nested DTOs. E. g. AddressDto inside PersonDto. How to configure source gen for that case? What would happen if nested DTO doesn’t have source gen but a parent does? What would happen if parent DTO has source gen, but nested doesn’t? What if I have a DTO that has 3 nested levels: CompanyDto that has EmployeeDto[] where each one has AddressDto, and source gen is configured only for CompanyDto and AddressDto?

  3. How one should handle collections of different types? What types of collections should be marked for source generation? Suppose I have these 3 cases:

    • nested IReadOnlyCollection<AddressDto> Addresses property inside PersonDto;
    • some controller to GET addresses that returns ActionResult<IEnumerable<AddressDto>>;
    • some controller to POST AddressDto.

    Should I add to source gen all three: IReadOnlyCollection<AddressDto>, IEnumerable<AddressDto>, AddressDto? Or if just IEnumerable<AddressDto> andAddressDto would suffice?

  4. What about controller action return type Task<ActionResult<IEnumerable<OrderDto>>>: what should be added in this case for source gen? What if the actual variable that is returned inside the controller is List<OrderDto> or HashSet<OrderDto> (while the controller’s action method signature is Task<ActionResult<IEnumerable<OrderDto>>>) = will the IEnumerable<OrderDto> mentioned in source-gen suffice?

  5. Is there any way to know if some cases are missed? E. g. if OrderDto is added, but IEnumerable<OrderDto> is not? To paraphrase, is there any way have some warnings during at least runtime(?) if reflection instead of source gen stuff have been used for (de)serialization in API controllers.

Overall UX thoughts

One would think who would not like to have free performance gains of using JSON source gen in Web APIs. Unfortunately current implementation feels like something one should wait for better times before implementing in their code. Something that was half-baked and rushed as a need for some specific case and that is not ready for actual API projects — too much manual boilerplate and not error-prone. Though I may be proven utterly wrong given more detailed docs/guides emerge.

One could ask for an option to apply JsonSerializable attributes directly to DTO classes instead of some separate context, or many other things like not having to think about collections (e. g. adding OrderDto would automatically handle cases for IEnumerable<OrderDto>).

Of course, ideal case would be not to think about this at all. One possible solution is to have another source generator or T4 template (akin to Entity Framework DB first) that would automatically generate required “json source generator” boilerplate for all .cs files located inside project DTO folder. Is it really the intended way to manually write hundreds of [JsonSerializable(typeof(insert_every_dto_type_name_here_and_collection_permutation))]?


Document Details

Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.

piskov avatar Oct 03 '23 23:10 piskov