如何设计一个具有正确语义的restful API?

时间:2015-03-05 04:19:56

标签: angularjs api rest soap restful-architecture

例如,在向用户出售订阅时 - 系统将执行的操作是

  • 创建一个组织
  • 创建用户
  • 创建订阅
  • 创建身份验证
  • 创建发送电子邮件
  • 基于业务逻辑的更多操作

以上所有需要在SAME DB事务中作为工作单元发生。

在SOAP语义中,它可以被抽象为register(organisation, User, Plan, authentication details..more parameters)并返回subscription个对象。

但是在Restful World中,我们只会处理HTTP动词的资源(只有URL中的名词),我发现很难描述这种与业务相关的逻辑而不是简单的CRUD?

2 个答案:

答案 0 :(得分:0)

不要求RESTFUL接口以1:1的方式映射到API后面的数据库。

您案例中的逻辑可能是:

client -- POST: SubscriptionRequests(request) --> Server
client <-- RESPONSE: Status|Error   --  Server

成功后,状态响应可能包含包含生成新条目的URI的属性。例如:SubscriptionURI = "Subscriptions/ID49343" UserURI="Users/User4711"

然后有人可以通过以下方式询问有效订阅:

client -- GET: Subscriptions               --> Server
client <-- RESPONSE: Subscriptions | Error --  Server

这个方案可以被认为是RESTful。事实上,服务器必须操纵数据库(客户端不可见)以及它是如何操作的。

与SubscriptionRequest操作执行之前相比,订阅资源(和用户资源)上的后续GET操作产生不同的输出也没有问题。

创建一个更加繁琐的界面也没有令人信服的理由,只是因为你碰巧有一些特定的数据库建模。
从这个意义上讲,如果你创建了一个像

这样的API,它会更糟
client -- POST: Users(newUser)    --> Server
client <-- RESPONSE: Status|Error -- Server
(if adding user worked bla bla ... )
client -- POST: Subscriptions(userId,other data..) --> Server
client <-- RESPONSE: Status|Error  -- Server

这基本上只是意味着你没有设计你的API,只是简单地复制了你的数据库表的结构(这些将在下周改变)。

总之,关注实现如何处理数据库并不是API设计的业务。如果您需要事务或者使用其他方法来确保完成所有需要完成的事情,那就是SubscriptionRequests.POST处理程序的实现。

答案 1 :(得分:0)

实际上,您认为使用RPC模式; - )

使用REST,您必须考虑使用资源和表示。您要做的是添加订阅,因此我建议使用实现注册的方法POST来获取订阅列表资源。在请求有效负载中,您将提供订阅所需的内容,并获取有关已创建订阅的提示。

以下是请求的示例:

POST /subscriptions/
{
    "organization": {
        "id": "organizationId",
        "name": "organization name",
        (...)
    },
    "user": {
        "lastName": "",
        (...)
    }
}

以下是回复示例:

{
    "id": "subscriptionId",
    "credentials": {
        (...)
    },
    (...)
}

您可以注意到有效负载是提案,可能与您的订阅,用户,...结构不完全匹配。所以请随意调整它们。

希望它可以帮到你, 亨利