c# - ServiceStack REST API 设计

标签 c# web-services rest servicestack

我开始尝试使用 ServiceStack,到目前为止我很喜欢它,但我认为我的设计从一开始就存在缺陷。本质上,我有一个通过 NHibernate 访问的 MSSQL 数据库。由于我的请求/响应 DTO 和服务应该采用什么样的结构,我开始感到困惑。

我在 MyProject.Common.Models 下的单独项目中有我的 NHibernate 映射,它包含一个“Client”类,如下所示:

namespace MyProject.Common.Models
{
    public class Client
    {
        public virtual int ClientID { get; set; }
        public virtual string Name { get; set; }
        public virtual string Acronym { get; set; }
        public virtual string Website { get; set; }
    }

    public class ClientMap : ClassMap<Client>
    {   
        public ClientMap()
        {
            Id(x => x.ClientID, "ClientID").GeneratedBy.Identity();

            Map(x => x.Name, "Name");
            Map(x => x.Acronym, "Acronym");
            Map(x => x.Website, "Website");
        }
    }
}

我想为客户端提供对单个客户端进行 CRUD 以及显示所有客户端列表的能力。到目前为止,我已经像这样设计了我的单个客户端请求:

[Route("/clients/{Id}", "GET")]
public class ClientRequest : IReturn<ClientResponse>
{
    public string Id { get; set; }
}

public class ClientResponse : IHasResponseStatus
{
    public MyProject.Common.Models.Client Client { get; set; }
    public ResponseStatus ResponseStatus { get; set; }

    public ClientResponse()
    {
        this.ResponseStatus = new ResponseStatus();
    }
}

如您所见,这只是将我的模型类返回给客户端。使用这种设计,我完全不知道如何正确发布新客户端或更新现有客户端。此外,如果我想返回所有客户端的列表,我目前正在使用以下请求/响应 DTO:

[Route("/clients", "GET")]
public class ClientsRequest : IReturn<ClientsResponse>
{

}
public class ClientsResponse : IHasResponseStatus
{
    public List<MyProject.Common.Models.Client> Clients { get; set; }
    public ResponseStatus ResponseStatus { get; set; }

    public ClientsResponse()
    {
        this.ResponseStatus = new ResponseStatus();
    }
}

像这样的服务:

public ClientsResponse Get(ClientsRequest request)
{
    var result = currentSession.Query<Chronologic.Eve.Common.Models.Client>().ToList();

    if (result == null)
        throw new HttpError(HttpStatusCode.NotFound, new ArgumentException("No clients exist"));

    return new ClientsResponse
    {
        Clients = result
    };
}

这行得通,虽然我觉得这也不是实现我想要做的事情的最佳方式,并且给我一个丑陋的元数据页面,如下所示:

Ugly ServiceStack metadata

我觉得我忽略了这个设计非常简单,如果有人能向我建议如何简化设计,我将不胜感激。

谢谢。

最佳答案

您应该查看这些早期的帖子,它们将有助于使用 ServiceStack 进行 API 设计:

我不会重新散列上面包含的任何内容,而是重写我的做法。

您不需要 ResponseStatus 属性,因此您的服务可以返回干净的 DTO。

[Route("/clients", "GET")]
public class AllClients : IReturn<List<Client>> {}

[Route("/clients/{Id}", "GET")]
public class GetClient : IReturn<Client>
{
    public string Id { get; set; }
}

服务实现应该基于上述请求 DTO 直接进行。

使用上述 API,您的 C# 客户端调用站点现在看起来像:

List<Client> clients = service.Get(new AllClients());

Client client = service.Get(new GetClient { Id = id });

关于c# - ServiceStack REST API 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16071484/

相关文章:

java - play.libs.WS.WSRequestHolder.get() 切断部分请求?

java - REST 子资源定位器

c# - 如何在 Fluent-NHibernate 中级联插入父级、子级和组合列表

jquery - 调用共享WebMethod时出现未知Web方法异常

c# - ASP.NET MVC 回调后的 RedirectToAction

xml - 以简单、中立的方式通过 HTTP 发送 XML

java - 如何使用 Neo4J 和 java-rest-binding 获取深度请求的结果?

javascript - 通过 javascript 向 REST API 发送 POST 请求

c# - 当 BufferBlock 为空时,Async StreamWriter Loop 停止写入

c# - XNA、C# - 检查 Vector2 路径是否与另一个 Vector2 路径交叉