我正在设计一个 REST API,我想知道处理资源更新的推荐方法是什么。更具体地说,我将允许通过资源上的 PUT 进行更新,但是我应该在 PUT 请求的正文中允许什么?

  • 总是完整的资源结构?
  • 总是资源结构的子部分(改变的)?
  • 两者的结合?

  • 例如,以资源 http://example.org/api/v1/dogs/packs/p1 为例。
    此资源上的 GET 将提供以下内容:
    Request:
    GET http://example.org/api/v1/dogs/packs/p1
    Accept: application/xml
    
    Response:
    <pack>
      <owner>David</owner>
      <dogs>
        <dog>
          <name>Woofer</name>
          <breed>Basset Hound</breed>
        </dog>
        <dog>
          <name>Mr. Bones</name>
          <breed>Basset Hound</breed>
        </dog>
      </dogs>
    </pack>
    

    假设我想在包中添加一只狗(Sniffer the Basset Hound),我是否支持:
    Request:
    PUT http://example.org/api/v1/dogs/packs/p1
    <dog>
      <name>Sniffers</name>
      <breed>Basset Hound</breed>
    </dog>
    
    Response:
    HTTP/1.1 200 OK
    

    或者
    Request:
    PUT http://example.org/api/v1/dogs/packs/p1
    <pack>
      <owner>David</owner>
      <dogs>
        <dog>
          <name>Woofer</name>
          <breed>Basset Hound</breed>
        </dog>
        <dog>
          <name>Mr. Bones</name>
          <breed>Basset Hound</breed>
        </dog>
        <dog>
          <name>Sniffers</name>
          <breed>Basset Hound</breed>
        </dog>
      </dogs>
    </pack>
    
    Response:
    HTTP/1.1 200 OK
    

    或两者?如果建议通过结构的小节支持更新,我将如何处理删除(例如当一只狗死亡时)?通过查询参数?

    最佳答案

    是的,始终发送资源的完整表示。否则,您将(根据 PUT 的常见定义和用法)仅用这只狗替换背包。

    但是,您可能需要考虑以下几点:

  • 在 URL 路径之外使用 XML 命名空间或其他版本控制方式(例如 ?version=2)
  • 将您要添加的狗发布到/dogs/packs/p1。 POST 根据定义创建一个从属资源,以便将狗添加到包中。
  • 稍微翻新一下您的 URL。在我看来,你真的想要/dogs/1234、/dogs/1235 等等,然后是/packs/p1、/packs/p2。然后你也可以简单地将 <dog id="1"> POST 到包中。

  • 请记住,REST 要求您正确识别资源。包并不是狗的真正从属资源,每只狗都应该有某种独特的标识符。然后,在访问/packs/p1/1234 时,您可能希望重定向到/dogs/1234。或者,尽管接受将下级资源发布到相应的包,您也不会使该 URL 可用。

    我想得越多,POST 方法就越有意义。也许你甚至可以为所有的狗创建一个/packs/p1/dogs/资源,与包分开。然后,您可以将所有者信息等内容放入/packs/p1,通过/packs/p1/dogs/获取所有狗的列表(其中应包含包中每只狗的 URL 列表,例如/packs/p1/dogs/1234,参见 HATEOAS ),通过 POST 到/packs/p1/dogs/将一条新狗添加到包中,并通过删除/packs/p1/dogs/1235 删除一条狗。每只狗都可以是完整的表示,甚至可能重定向到/dogs/1234 等,或者在此包的上下文中狗的不同表示,但同样带有指向“完整”狗的链接。取决于你想如何代表一个包中的一只狗,这当然也会影响你实际发布到/packs/p1/dogs/的内容。 Full dog 感觉不对,真的应该只是我上面展示的一个ID,也许还有关于与包关系的额外数据。

    关于http - 在 REST API 中使用 PUT 进行更新时是否应该允许发送完整的结构?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2719610/

    10-12 05:11