假设我有一个客户可以归属的俱乐部列表。我有FindClubs
路线将返回客户可以注册的所有俱乐部。我还有一条FindCustomerClubs
路线,给定CustomerId
将返回此特定客户所属的所有俱乐部。
然而,我不确定如何构建的俱乐部需要/拥有关于客户的其他信息。例如,假设我有一个生日俱乐部,需要客户孩子的姓名和生日加入。看起来这应该是另一个更具体的路线,比如/clubs/birthday
。对于那些不仅希望获得客户加入的俱乐部列表的客户,以及每个俱乐部要显示的附加信息,如孩子的生日,我该如何构建?
我发现this post不推荐使用HATEOS。我可以理解客户端不会自动获取各种新数据和行为。他们需要知道调用更具体的路线才能获得它。但是,客户必须知道ClubId
123是生日俱乐部是不对的,所以如果他们想要生日,他们需要打电话给生日路线?或者是否有另一种建议的方法来避免将ID或描述紧密耦合到其他路由?我讨厌看到所有需要switch语句的客户端应用程序根据返回的ClubIds执行另一次查找,如果该数字更改,一切都将变得混乱。
[Route("/clubs", "GET", Summary = Summary.FindClubs)]
public class FindClubs : IReturn<List<CustomerClub>> { }
public class CustomerClub
{
public int ClubId { get; set; }
public string ClubName { get; set; }
}
[Route("/customers/{" + nameof(CustomerId) + "}/clubs", "GET", Summary = Summary.FindCustomerClubs)]
public class FindCustomerClubs : IReturn<List<CustomerClub>>
{
[ApiMember(Description = Description.CustomerId)]
public int CustomerId { get; set; }
}
答案 0 :(得分:2)
首先,我建议设计coarse-grained message-based APIs,其中我有不同的服务返回每个聚合根的数据,我会在客户端使用后建模,例如,如果客户需要查找客户生日以及哪些俱乐部他们我的成员将在相同的客户服务中归还,例如:
[Route("/customer/{Id}", "GET")]
public class GetCustomer : IReturn<GetCustomerResponse>
{
public int Id { get; set; }
}
public class GetCustomerResponse
{
public Customer Customer { get; set; }
public List<Club> Clubs { get; set; }
}
理想情况下,服务应该是自我描述的,所以我不会返回一个ClubIds整数列表,而是返回整个俱乐部数据模型。
如果整个俱乐部包含太多信息,那么我将返回一个新的DTO,其中只包含客户需要的信息,例如,如果他们只需要显示客户所属俱乐部的名称,我就会创建一个单独的DTO,如:
public class ClubSummary
{
public int Id { get; set; }
public string Name { get; set; }
}
public class GetCustomerResponse
{
public Customer Customer { get; set; }
public List<ClubSummary> Clubs { get; set; }
}