【问题标题】:correct REST approach for hierarchy Inserts and Updates层次结构插入和更新的正确 REST 方法
【发布时间】:2016-03-16 12:41:51
【问题描述】:

假设我有以下课程:

company 
user
address

公司对象可以包含用户和地址, 用户对象包含地址

公司可以独立存在,但用户和地址始终是公司或用户的一部分(UML 措辞中的组合):

company ->
          addresses
          users ->
                  addresses

现在我想为 POST(插入)和 PUT(更新)请求使用正确的 REST 结构。正确的做法是什么?

变体 1:

// insert address:
POST /api/company/{companyId}/addresses
POST /api/company/{companyId}/users/{userId}/addresses
// update address:
PUT /api/company/{companyId}/addresses/{addressId}
PUT /api/company/{companyId}/users/{userId}/addresses/{addressId}

变体 2:

// insert address:
POST /api/address // companyId, userId etc. as parameter
// update address:
PUT /api/address/{addressId}

我个人的直觉是使用变体 1 进行创建 (POST) 和变体 2 进行更新 (PUT),因为变体 1 在创建时看起来“更干净”,但更新变体 2 会更好,因为它不需要parentId(公司或用户)

【问题讨论】:

    标签: rest


    【解决方案1】:

    首先,REST 是一种架构风格,而不是一种协议。这意味着您定义 URI 的方式没有对错之分。 Roy Fielding 提出的唯一要求是每个资源都必须具有唯一的资源标识符 (URI)。您可以对这些 URI(动词)执行的操作由底层超文本传输​​协议 (HTTP) 定义。

    其次,有一些最佳实践,例如将子资源用于嵌入在其他资源中的资源(尤其是如果没有父资源它们就无法存在),例如 addressesusers/ companies

    由于您在更新子资源时遇到某些问题:

    通常使用 HTTP 动词 PUT 更新资源,它的限制是用您发送到服务器的状态替换当前状态(所有可用数据)(以防更新顺利)。由于在 HTTP 中还没有定义部分更新,一些使用 PUT 动词有点模糊,只更新请求中可用的内容,尽管发出 PATCH 请求并且只更新这些字段在 HTTP 方面可能更正确规格。

    子资源与常规资源非常相似。如果更新子资源,则不需要更新父资源。在您的特定情况下,如果您想更新用户的地址而不是用户本身,您可以向服务器发出包含地址新状态的 PUT /users/{userId}/addresses/{addressId} HTTP/1.1 请求。请求正文可能如下所示:

    {
        "street": "Sample Street 1"
        "city": "Sampletown",
        "zip": "12345",
        "country": "Neverland",
        "_links": {
            "self": { "href": "/users/{userId}/addresses/{addressId} }
            "googleMap": { "href": "https://www.google.com/maps/place/Liberty+Island/@40.6883129,-74.042817,16.4z/data=!4m2!3m1!1s0x0000000000000000:0x005f3b2fa5c0821d" }
        }
    }
    

    如果您想严格遵循 HTTP PUT 动词并拥有可能在运行时出现的动态字段,您可能最终必须更改当前表定义,删除旧地址条目并使用提供的地址插入新条目信息(取决于您使用 SQL 与 NoSQL 的数据库层)。注意 HTTP PUT 动词语义!

    在使用模糊更新策略(=部分更新)时,一个简单的更新语句应该没问题。在这里,您可以简单地忽略包含在 URI 中的附加 userId,尽管这(还)不是完全符合 HTTP 的——至少在规范方面是这样。在这种特殊情况下,您可以选择选择哪个版本的 URI,但版本 2 仅适用于后一种情况,而版本 1 则适用于两种情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-30
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      • 2015-05-14
      • 2013-11-21
      • 2016-06-22
      相关资源
      最近更新 更多