2014-01-06 4 views
6

У меня возникла проблема с реализацией Swagger в ServiceStack в отношении документации типизированных объектов ответа. Сильно типизированные объекты ответа правильно документируются и отображаются, однако, как только типично типизированный объект используется в качестве ответа, документация является неточной и вводящей в заблуждение.Общепринятый объект ответа, который не точно документирован в Swagger (ServiceStack)

Запрос DTO

[Route("https://stackoverflow.com/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 Тип

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

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; } 
} 

Пример s довольно прямолинейны. Ничто действительно Hacky или умна происходит, однако это не является документация образец, я получаю от Swagger из коробки:

Swagger Example

Как вы можете видеть, общий тип не документированы правильно и какой-либо другой тип используется вместо этого. Поскольку я использую эту ту же самую оболочку ServiceResponse для всех своих ответов, это происходит по всем направлениям.

ответ

2

Как вы нашли, плагин для плагинов ServiceStack в настоящее время не пытается обработать общие типы. Простой альтернативой, которая должна работать лучше, является создание конкретных подклассов общих типов. например:

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

public class GetUser : IReturn<UserProfileResponse> ... 

Это должно быть правильно обработано Swagger.

Я нашел, что общие типы не всегда подходят для DTO ServiceStack. Вы найдете много обсуждений (например, here, here и here) на StackOverflow, которые обсуждают это, и причины, по которым конкретные типы и вообще избегают наследования, являются хорошей идеей для DTO ServiceStack.

Требуется усилие, чтобы преодолеть соблазн применить принцип DRY для запроса/обработки DTO. Способ, которым я об этом думаю, заключается в том, что дженерики и наследование - это языковые функции, которые облегчают реализацию алгоритмов в общих, многоразовых способах, когда общий метод или базовый класс не должен знать о деталях конкретного типа. Хотя DTO могут иметь общие структуры, которые выглядят как возможности для наследования или дженериков, в этом случае реализация и семантика каждой DTO различаются для каждого конкретного использования, поэтому детали каждого сообщения запроса/ответа заслуживают определения явно.

+2

Спасибо за ответ. Совет по использованию дженериков и наследованию в DTS ServiceStack звучит и понимается. Тем не менее, мы пытаемся использовать общую библиотеку домена/DTO для наших веб-клиентов или мобильных клиентов для облегчения безопасности типов после десериализации. При этом я пытался уйти от создания нового ответа DTO для каждого типа домена, который будет возвращаться, но скорее используйте generics для указания типа домена, который будет содержать общий ответ. В конечном счете это была мера экономии времени/кода, которая, возможно, укусила нас позади, когда дело касается документации. Еще раз спасибо! –

Смежные вопросы