简体   繁体   English

使用RESTful处理子对象上的CRUD

[英]Handling CRUD on child objects with RESTful

If given the following xml request sent to a RESTful API endpoint called /catalog via a PUT (Intent to update catalog). 如果给出以下xml请求,则该XML请求通过PUT发送到名为/ catalog的RESTful API端点(意图更新目录)。

If the user provides additional <book> s that don't exist at that point in the catalog in the request should the endpoint "Create" them? 如果用户提供了请求中目录中当时不存在的其他<book> ,则端点应该“创建”它们吗? or should they be ignored and a different endpoint perhaps /books be used to create them. 还是应该忽略它们,并使用其他端点/ books来创建它们。

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
   </book>
   <book id="bk104">
      <author>Corets, Eva</author>
      <title>Oberon's Legacy</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-03-10</publish_date>
      <description>In post-apocalypse England, the mysterious 
      agent known only as Oberon helps to create a new life 
      for the inhabitants of London. Sequel to Maeve 
      Ascendant.</description>
   </book>
   <book id="bk105">
      <author>Corets, Eva</author>
      <title>The Sundered Grail</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-09-10</publish_date>
      <description>The two daughters of Maeve, half-sisters, 
      battle one another for control of England. Sequel to 
      Oberon's Legacy.</description>
   </book>
   <book id="bk106">
      <author>Randall, Cynthia</author>
      <title>Lover Birds</title>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-09-02</publish_date>
      <description>When Carla meets Paul at an ornithology 
      conference, tempers fly as feathers get ruffled.</description>
   </book>
   <book id="bk107">
      <author>Thurman, Paula</author>
      <title>Splish Splash</title>
      <genre>Romance</genre>
      <price>4.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>A deep sea diver finds true love twenty 
      thousand leagues beneath the sea.</description>
   </book>
   <book id="bk108">
      <author>Knorr, Stefan</author>
      <title>Creepy Crawlies</title>
      <genre>Horror</genre>
      <price>4.95</price>
      <publish_date>2000-12-06</publish_date>
      <description>An anthology of horror stories about roaches,
      centipedes, scorpions  and other insects.</description>
   </book>
   <book id="bk109">
      <author>Kress, Peter</author>
      <title>Paradox Lost</title>
      <genre>Science Fiction</genre>
      <price>6.95</price>
      <publish_date>2000-11-02</publish_date>
      <description>After an inadvertant trip through a Heisenberg
      Uncertainty Device, James Salway discovers the problems 
      of being quantum.</description>
   </book>
   <book id="bk110">
      <author>O'Brien, Tim</author>
      <title>Microsoft .NET: The Programming Bible</title>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-09</publish_date>
      <description>Microsoft's .NET initiative is explored in 
      detail in this deep programmer's reference.</description>
   </book>
   <book id="bk111">
      <author>O'Brien, Tim</author>
      <title>MSXML3: A Comprehensive Guide</title>
      <genre>Computer</genre>
      <price>36.95</price>
      <publish_date>2000-12-01</publish_date>
      <description>The Microsoft MSXML3 parser is covered in 
      detail, with attention to XML DOM interfaces, XSLT processing, 
      SAX and more.</description>
   </book>
   <book id="bk112">
      <author>Galos, Mike</author>
      <title>Visual Studio 7: A Comprehensive Guide</title>
      <genre>Computer</genre>
      <price>49.95</price>
      <publish_date>2001-04-16</publish_date>
      <description>Microsoft Visual Studio 7 is explored in depth,
      looking at how Visual Basic, Visual C++, C#, and ASP+ are 
      integrated into a comprehensive development 
      environment.</description>
   </book>
</catalog>

I am finding a lot on SO that talks about PUT vs POST and best practices for doing CRUD operations on a root object but I've spent the night trying to find information around how child objects should be handled. 我在SO上发现了很多内容,这些内容讨论了PUT与POST以及对根对象执行CRUD操作的最佳实践,但是我花了一整夜的时间来寻找有关应如何处理子对象的信息。

According to http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html it isn't clear to me if this applies to child objects? 根据http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html ,我不清楚这是否适用于子对象?

9.6 PUT 9.6放置

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. PUT方法请求将封闭的实体存储在提供的Request-URI下。 If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. 如果Request-URI引用了已经存在的资源,则应将封闭的实体视为驻留在原始服务器上的实体的修改版本。 If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI. 如果Request-URI没有指向现有资源,并且请求用户代理能够将该URI定义为新资源,则原始服务器可以使用该URI创建资源。 If a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. 如果创建了新资源,则原始服务器务必通过201(已创建)响应通知用户代理。 If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request. 如果修改了现有资源,则应发送200(确定)或204(无内容)响应代码以指示请求已成功完成。 If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be given that reflects the nature of the problem. 如果无法使用Request-URI创建或修改资源,则应给出反映问题性质的适当错误响应。 The recipient of the entity MUST NOT ignore any Content-* (eg Content-Range) headers that it does not understand or implement and MUST return a 501 (Not Implemented) response in such cases. 实体的接收者不得忽略其无法理解或实现的任何Content-*(例如Content-Range)报头,并且在这种情况下必须返回501(未实现)响应。

From my understanding of REST, books are resources and should be handled through their own endpoint and an update to the catalog should only be used to add existing books to a catalog, not create them. 根据我对REST的理解,书籍是资源,应该通过它们自己的端点进行处理,并且对目录的更新仅应用于将现有书籍添加到目录中,而不是创建它们。

So in this scenario a book that does not exist would be ignored/not added to the catalog until a create request is submitted to create the book. 因此,在这种情况下,不存在的书将被忽略/不添加到目录中,直到提交创建请求以创建书。

This would mean the user would send a POST /book to create the book, followed by a PUT to /catalog with the book in the request to add it to the catalog. 这意味着用户将发送一个POST / book来创建该书,然后向/ catalog发送一个PUT并将请求中的书添加到目录中。

You're right. 你是对的。 You have two different resources here. 您在这里有两种不同的资源。 One is named Books and the other is named Catalogs. 一个叫做书,另一个叫做目录。 You must design two different URIs to address each one. 您必须设计两个不同的URI来寻址每个URI。 So in this scenario, I'd create two different resources to handle this problem. 因此,在这种情况下,我将创建两个不同的资源来处理此问题。 The first resource would be named as /catalogs and you must build it to receive only the book ID (one or more) that someone wants to associate with this catalog. 第一个资源将被命名为/ catalogs,并且您必须构建它以仅接收某人想要与此目录关联的书籍ID(一个或多个)。 You'll have: 您将拥有:

Endpoint -> https://yourapi.com/catalogs

POST to https://yourapi.com/catalogs --> creates a new catalog.
PUT to https://yourapi.com/catalogs/1 --> updates the catalog with ID = 1.
PUT to https://yourapi.com/catalogs/2 where id 2 doesn't exist --> creates a new catalog with id=2

You have to send the XML below to the endpoint pointed above. 您必须将下面的XML发送到上面指出的端点。

<?xml version="1.0"?>
<catalog>
    <book id="bk101"/>
    <book id="bk102"/>
    <book id="bk103"/>
    <book id="bk104"/>
<catalog>

The second resource should be /books and you must use it to create, delete, update and list books. 第二个资源应该是/ books,并且您必须使用它来创建,删除,更新和列出书籍。 Once you've created a book, then you can associate it with a catalog. 创建书籍后,即可将其与目录相关联。 You shouldn't use the resource Catalogs to create a Book that way. 您不应该使用资源目录以这种方式创建一本书。 To my mind, it doesn't make sense. 在我看来,这没有任何意义。

What you are trying to do is a bulk/batch update. 您试图做的是批量/批量更新。 Afaik. 据我所知。 we don't have consensus how to do that. 我们对此没有达成共识。 There are many issues here: 这里有很多问题:

  • PUT should be used by updating the whole resource. 应该通过更新整个资源来使用PUT。 Since the resource is /catalog (so every single book in your storage) here, you have to give a representation of the whole catalog. 由于此处的资源为/catalog (因此存储中的每一本书),因此您必须提供整个目录的表示形式。 You should consider PATCH instead, which can be used for partial update. 您应该考虑使用PATCH,它可以用于部分更新。
  • PUT is idempotent. PUT是幂等的。 So if you send a PUT twice it should not have any side effect. 因此,如果您发送两次PUT,则不会有任何副作用。 That's why you can use PUT for creation only if the users give the id of the new resources. 这就是为什么仅当用户提供新资源的ID时才可以使用PUT进行创建的原因。 (Otherwise you would create the new resource twice.) PATCH is not idempotent, so 2:0 to PATCH. (否则,您将创建两次新资源。)PATCH不是幂等的,因此2:0对应PATCH。

You can find a description about PATCH here: PATCH Method for HTTP . 您可以在此处找到有关PATCH的描述: HTTP的PATCH方法

With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version. 但是,对于PATCH,封闭的实体包含一组指令,这些指令描述了应如何修改当前驻留在源服务器上的资源以产生新版本。 The PATCH method affects the resource identified by the Request-URI, and it also MAY have side effects on other resources; PATCH方法影响由Request-URI标识的资源,并且可能对其他资源也有副作用。 ie, new resources may be created, or existing ones modified, by the application of a PATCH. 也就是说,可以通过应用PATCH来创建新资源或修改现有资源。

So PATCH /catalog and your XML would be okay. 因此, PATCH /catalog和您的XML都可以。 You can decide whether you allow your users to give the id of the new resources, or you can generate it on server side. 您可以决定是否允许用户提供新资源的ID,或者可以在服务器端生成它。

Ofc. OFC。 you have alternatives, for example you can send a book collection with POST /catalog , so multiple book resources will be created. 您有其他选择,例如,您可以使用POST /catalog发送书籍收藏,因此将创建多个书籍资源。 You can use PUT /catalog/?id="bk112,bk113,..." to update a specific collection of books. 您可以使用PUT /catalog/?id="bk112,bk113,..."更新特定的书籍集合。 Another alternative to create everything one by one, as you already mentioned. 如前所述,另一种创建所有内容的方法。

Be aware that we are talking about hyperlinks ( METHOD /resource-id?query <data /> + link metadata: eg link relation ). 请注意,我们在谈论超链接( METHOD /resource-id?query <data /> + link metadata: eg link relation )。 So you should consider to add links to your resource representations you return by a GET and probably use a hypermedia format as well eg HAL+XML or ATOM+XML. 因此,您应该考虑将链接添加到由GET返回的资源表示形式,并且还可能使用超媒体格式,例如HAL + XML或ATOM + XML。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM