Swagger(ServiceStack)中未准确记录通用类型的响应对象

时间:2014-01-06 14:26:54

标签: servicestack swagger swagger-ui

关于泛型类型响应对象的文档,我遇到了Swagger的ServiceStack实现问题。强类型响应对象被正确记录和显示,但是一旦使用泛型类型的对象作为响应,文档就不准确并且会产生误导。

申请DTO

[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

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

这些例子很简单。没有什么真正hacky或聪明的继续,但这是我从Swagger开箱即用的示例文档:

Swagger Example

如您所见,通用类型未正确记录,而是使用了其他类型。当我使用相同的ServiceResponse包装器来处理所有响应时,这种情况正在全面发生。

1 个答案:

答案 0 :(得分:2)

正如您所发现的,ServiceStack swagger插件目前不会尝试干净地处理泛型类型。应该更好地工作的简单替代方法是制作泛型类型的具体子类。 e.g:

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

public class GetUser : IReturn<UserProfileResponse> ...

这应该由Swagger妥善处理。

我发现泛型类型并不总是非常适合ServiceStack DTO。您将在StackOverflow上找到许多讨论这些内容的讨论(例如hereherehere),以及为什么具体类型和一般避免继承对ServiceStack DTO来说是个好主意的原因

需要努力克服应用DRY原则来请求/响应DTO的诱惑。我认为它的方式是泛型和继承是语言特性,它以通用的,可重用的方式实现算法的实现,其中泛型方法或基类不需要知道具体类型的细节。虽然DTO可能表面上看起来像继承或泛型的机会,但在这种情况下,每个DTO的实现和语义对于每个具体用法都是不同的,因此每个请求/响应消息的详细信息都应该明确定义。