A common response object is not well documented in Swagger (ServiceStack)

I had a problem implementing Swagger in ServiceStack regarding documentation of typed response objects. Strongly typed response objects are correctly documented and displayed, however, as soon as a typically typed object is used as an answer, the documentation is inaccurate and misleading.

DTO Request

[Route("/users/{UserId}", "GET", Summary = "Get a specific User Profile")] public class GetUser : IReturn<ServiceResponse<UserProfile>> { [ApiMember(Description = "User Id", ParameterType = "path", IsRequired = true)] public int UserId { get; set; } } 

DTO answer

 public class ServiceResponse<T> : IServiceResponse<T> { public IList<string> Errors { get; set; } public bool Successful { get; set; } public string Message { get; set; } public string StackTrace { get; set; } public T Data { get; set; } public ServiceResponse() { Errors = new List<string>(); } } 

DTO response type

 public class UserProfile : RavenDocument { public UserProfile() { Races = new List<UserRace>(); Workouts = new List<Workout>(); } public string FirstName { get; set; } public string LastName { get; set; } public string DisplayName { get; set; } public DateTime? BirthDate { get; set; } public Gender? Gender { get; set; } public string UltracartPassword { get; set; } public string UltracartCartId { get; set; } [UniqueConstraint] public string Email { get; set; } public string ImageUrl { get; set; } public FacebookUserInfo FacebookData { get; set; } public GoogleUserInfo GoogleData { get; set; } public DateTime CreatedOn { get; set; } public DateTime? LastUpdated { get; set; } public UserAddress ShippingAddress { get; set; } public UserAddress BillingAddress { get; set; } public IList<UserRace> Races { get; set; } public IList<Workout> Workouts { get; set; } } 

The examples are pretty straightforward. Nothing serious or hacked, but this is a sample of the documentation I get from Swagger out of the box:

Swagger example

As you can see, the generic type is not documented correctly, but a different type is used instead. Since I use this same ServiceResponse wrapper for all my answers, this happens in all directions.

+6
source share
1 answer

As you already found, the Swartger ServiceStack plugin is not currently trying to handle generic types. A simple alternative that should work better is to create specific subclasses of common types. eg:.

 public class UserProfileResponse : ServiceResponse<UserProfile> { ... } public class GetUser : IReturn<UserProfileResponse> ... 

This must be handled correctly by Swagger.

I found that generic types are not always suitable for DTO ServiceStack. You will find many discussions (like here , here and here ) on StackOverflow that discuss this, and the reasons why specific types generally avoid inheritance, are a good idea for DTO ServiceStack.

It takes a lot of effort to overcome the temptation to apply the DRY principle to request / process DTOs. The way I think about this is that generics and inheritance are language functions that make it easier to implement algorithms in general, reusable ways when the general method or base class does not need to know about the details of a particular type. Although DTOs may have common structures that look like inheritance or generics, in this case, the implementation and semantics of each DTO are different for each specific use, so the details of each request / response message deserve explicit definition.

+2
source

All Articles