我对 ServiceStack 相当陌生,我正在尝试找出处理同一请求上的多个 get 操作的最佳实践。以下是我的请求对象:
[Route("/Entity", Verbs = "GET", Notes = "Returns all the entities.")]
[Route("/Entity/{Id}", Verbs = "GET", Notes = "Returns a specific entity.")]
[Route("/Entity/{Id}/Child", Verbs = "GET", Notes = "Returns children of a specific entity.")]
public class EntityRequest {
public int Id { get; set; }
public int ChildId { get; set; }
}
以下是我的服务:
public object Get(EntityRequest request) {
if (request.Id > 0) {
//returns a given entity
return _applicationService.getEntities(request.Id);
}
//How do I handle this? Check for the word "/Child" in the URL?
//returns children for a given entity
//return _applicationService.getChildren(request.Id);
//returns all the entities
return _applicationService.getEntities();
}
}
如您所见,我正在从服务端处理前两条路由“/Entity”和“/Entity/{Id}”。如何最好地处理“/Entity/{Id}/Child”路线?在当前状态下,第三个 URL 将返回所有实体。任何帮助将不胜感激?
谢谢!
最佳答案
看看下面这些现有的答案,其中介绍了使用 ServiceStack 设计服务的推荐方法:
- Designing a REST-ful service with ServiceStack
- Simple Customer REST Example
- How to design a Message-Based API
如果响应不同,建议使用不同的服务。你的服务也应该是 self 描述的,而不是依赖注释中的文档来描述每个服务(很少有人读),所以我会把你的服务重新设计成这样:
[Route("/entities")]
public class GetAllEntities : IReturn<GetAllEntitiesResponse> {}
public class GetAllEntitiesResponse
{
public List<Entity> Results { get; set; }
}
如果您还希望您的服务能够提供查询实体的能力,请查看 AutoQuery它允许您仅使用下面的请求 DTO 创建完全可查询的 RDBMS 支持的服务:
[Route("/entities/search")]
public class QueryEntities : QueryBase<Entity> {}
其余服务类似于每种不同类型服务的单独请求 DTO,其中请求 DTO 将包含调用该服务所需的所有属性,例如:
[Route("/entities/{Id}")]
public class GetEntity : IReturn<GetEntityResponse>
{
public int Id { get; set; }
}
public class GetEntityResponse
{
public Entity Result { get; set; }
}
对于子实体服务也是如此:
[Route("/entities/{Id}/children")]
public class GetEntityChildren : IReturn<GetEntityChildrenResponse>
{
public int Id { get; set; }
}
public class GetEntityChildrenResponse
{
public List<EntityChild> Results { get; set; }
}
以这种方式设计您的服务可以明确每个服务的作用、每个服务期望的参数以及它返回的内容。当使用ServiceStack's Typed Service Clients调用上述服务时也会反射(reflect)出来。 ,例如:
var response = client.Get(new GetAllEntities());
var response = client.Get(new GetEntity { Id = 1 });
var response = client.Get(new GetEntityChildren { Id = 1 });
我个人的偏好是对每个服务使用显式响应 DTO,因为它可以为服务提供 future 证明,并让您稍后改进服务以在不破坏现有服务客户端的情况下返回其他结果,但如果您愿意,您也可以返回结果直接无需显式响应 DTO 包装器,例如:
[Route("/entities")]
public class GetAllEntities : IReturn<List<Entity>> {}
[Route("/entities/{Id}")]
public class GetEntity : IReturn<Entity>
{
public int Id { get; set; }
}
[Route("/entities/{Id}/children")]
public class GetEntityChildren : IReturn<List<EntityChild>>
{
public int Id { get; set; }
}
关于routes - 处理多个 get 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36479454/