在 REST API 中定义操作

Posted

技术标签:

【中文标题】在 REST API 中定义操作【英文标题】:Defining operations in REST API 【发布时间】:2021-07-11 19:47:35 【问题描述】:

我正在处理一个消息请求,该请求将包含用于在目标中创建记录的完整请求详细信息。

此集成在不同时间创建 3 种不同类型的记录(订单、发货、发票),即并非总是可以一次创建所有记录,因此我需要让系统知道只创建某些请求。

我的问题,在请求中添加此信息的最佳方式是什么?

是否需要在请求正文中?


   "OrderNumber": "1234", 
   "operation": [
     "orderentry",
     "shipment",
     "invoice"
   ]

它需要在路径中吗?

 /Order/create?operation=orderentry

它需要在单独的对象中吗?说

 
   "operation": [
     "orderentry",
     "shipment",
     "invoice"
   ],
   "request": 
     "OrderNumber": "1234", 

   

【问题讨论】:

【参考方案1】:

请求的有效uri应该标识正在修改的文档;有效载荷应该是描述修改的文档。

POST /home.html
Content-Type: text/plain

Bob, please fix the spelling error in the title.  Thanks.

/home.html 标识我们正在修改的文档;正文告诉我们客户想要进行的修改。

uniform interface 约束确保每个人(服务器、客户端、中间组件)都以相同的方式解释此消息——请求的语义在任何地方都是相同的,响应的语义也是如此。

请注意,我们不会将请求发送到 /home.html?edit/home.html?operation=edit,因为它们是两个不同资源(我们知道这一点,因为标识符不同)。通过正确识别我们在请求中修改的资源,我们可以让通用组件清楚地知道发生了什么,以便它们可以做智能的事情(比如invalidating caches)。

信息是否需要在“单独的对象”中是架构设计的问题; HTTP 真的不在乎你在文档中使用什么模式 transferring over a network。

【讨论】:

【参考方案2】:

如果您只是想使用 HTTP 作为一种传输机制,那么一切顺利。另一方面,如果你想开发一个真正的 RESTful API,你应该学习 REST。首先,考虑Richardson maturity model。我不考虑 API RESTful,除非它是 3 级 API,但即使在 1 级,您也应该将 API 建模为一组资源

每个资源都应该由一个唯一的 URL 标识,因此已经排除了 OP 中三个选项中的两个。

资源应该通过它们的 URL 来标识,但不是按照建议的那样。在级别 2,操作由 HTTP 动词(GETPOSTDELETE 等)指示。因此,为了支持创建订单,我设想这样的 HTTP 请求:

POST /orders HTTP/1.1
Content-Type: application/json

  "orderNumber": 1234

成功的请求应该会导致 200 范围内的响应(200 OK201 Created 等)。

如果您想创建货件资源,您可以将POST 发送到shipments 收集资源:

POST /shipments HTTP/1.1
Content-Type: application/json

  "orderNumber": 1234

ordersshipments 等资源通常称为集合资源,因为它们代表其他资源的集合。它们通常仅支持POSTGET 动词,其中GET 将枚举集合中的所有资源。

针对集合资源的每个POST 通常会导致创建具有自己地址的“子资源”。例如,当您创建订单时,创建的地址可能是/orders/1234。这样的资源通常支持GETDELETE,也许还支持PUT,但不支持POST

我强烈推荐 Allamaraju Subrahmanyam 的书RESTful Web Services Cookbook,供任何想要进入 REST API 设计的人使用。它易于阅读且充满实用的解决方案。

【讨论】:

感谢您的回复。我将参考给定的参考资料。在我的源系统中,所有信息都存储在一个记录中,我理解资源应该在 URL 中标识并发送所需的正文。但要为特定订单创建货件,我需要插入订单。也可以一次创建所有 3 条记录(意味着源中的触发点已准备好),如果我触发所有 3 个单独的请求,目标可能没有准备好父记录?如何处理这种情况 @brahmajitammana REST API 不必反映数据库设计。您的数据库的结构应该是一个实现细节。如果您有更多问题(您似乎有),请发布新问题。当前的 OP 没有描述您现在引入的约束。

以上是关于在 REST API 中定义操作的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 to 参数定义 REST API

如何在 Delphi 中使用 DropBox REST API 复制文件

Ambari-Server Rest API处理2(Ambari-Server通过Rest API进行服务安装部署操作流程+操作源码分析)

如何在 Vuex 的操作中使用 axios 获取 Rest API 数据?

REST API:使用 C# 结合登录信息和 API 操作?

在同构通量应用程序中,是不是应该在操作中实现 REST api 调用?