【问题标题】:How to design a restful API with right semantic?如何设计一个具有正确语义的宁静 API?
【发布时间】:2015-03-05 04:19:56
【问题描述】:

例如,当向用户出售订阅时 - 系统会做的是

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

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

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

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

【问题讨论】:

  • 您希望所有这些事情发生在哪里?在数据库内部还是在您的业务逻辑中?如果你有类似存储过程的东西,你可以发布一个registration_request 项目,然后存储过程/触发器可以做所有的细节,比如在数据库端创建一个新用户等。或者你会有一些业务逻辑来查找registration_request 条目,然后处理它们(在后台)。基本上,如果您的 API 是 RESTful 的,并不意味着 API 背后的逻辑不适用于多个“资源”。或者你可以重新组合你的数据。
  • 根据我对 SOAP 与 RESTful 服务的了解,我相信唯一的区别是 SOAP 具有由它们的库文件定义的定义结构(我忘记了文件的扩展名)。所以基本上,RESTful API 可以用与 SOAP API 相同的语义来描述。

标签: angularjs api rest soap restful-architecture


【解决方案1】:

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 操作之前相比,对 Subscriptions 资源(和 Users 资源)的后续 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 处理程序的实现。

【讨论】:

    【解决方案2】:

    其实你认为使用RPC模式;-)

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

    这是请求的示例:

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

    以下是响应示例:

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

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

    希望对你有帮助 蒂埃里

    【讨论】:

    • 谢谢,这很有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 2012-07-27
    • 2011-10-29
    • 1970-01-01
    • 2011-07-21
    相关资源
    最近更新 更多