【问题标题】:Defining operations in REST API在 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", 
    
       }
    }
    

【问题讨论】:

    标签: design-patterns integration rest integration-patterns


    【解决方案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 没有描述您现在引入的约束。
      猜你喜欢
      • 1970-01-01
      • 2021-09-02
      • 2021-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多