REST复杂/复合/嵌套资源 [英] REST Complex/Composite/Nested Resources

查看:624
本文介绍了REST复杂/复合/嵌套资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想换我的头周围的最好办法,以解决基于REST API的概念。不包含其他资源平坦资源都没有问题。在那里我遇到的麻烦是复杂的资源。

I'm trying to wrap my head around the best way to address concepts in a REST based API. Flat resources that don't contain other resources are no problem. Where I'm running into trouble are the complex Resources.

比如我有ComicBook的资源。 ComicBook拥有各种属性就可以了,比如作者,发行数量,日期等。

For instance I have a resource for ComicBook. ComicBook has all sorts of properties on it like author, issue number, date, etc.

一本漫画书也有1..1盖列表。这些盖是复杂的对象。它们包含的封面,艺术家,日期,甚至带盖子的codeD映像基地64大量的信息。

A comic book also has a list of 1..n covers. These covers are complex objects. They contain a lot of information about the cover, artist, date, and even a base 64 encoded image of the cover.

有关ComicBook一个GET我可以回相声,和所有的封面,包括他们的base64'ed图像。这可能不是一个大问题得到一个单一的漫画。但是假设我建立一个想要列出所有的漫画在系统表中的一个客户端应用程序。该表将包含来自ComicBook资源的一些属性,但我们肯定不会希望在表中显示所有的封面。返回1000漫画,每个具有多个覆盖将导致大的离谱量数据通过线路来的,数据没有必要在这种情况下,最终用户。

For a GET on ComicBook I could just return the comic, and all of the covers including their base64'ed images. That's probably not a big deal for getting a single comic. But suppose I am building a client app that wants to list all of the comics in the system in a table. The table will contain a few properties from the ComicBook resource, but we're certainly not going to want to display all the covers in the table. Returning 1000 comic books, each with multiple covers would result in a ridiculously large amount of data coming across the wire, data that isn't necessary to the end user in that case.

我的直觉是要涵盖资源和ComicBook包含封面。所以,现在封面是一个URI。 GET对漫画书现在工作,而不是庞大的封面资源,我们每个盖发回URI和,因为他们要求他们的客户可以检索封面的资源。

My instinct is to make Cover a resource and ComicBook contains covers. So now Cover is a URI. GET on comic book works now, instead of the huge Cover resource we send back a URI for each cover and clients can retrieve the Cover resources as they require them.

现在我有创造新漫画的一个问题。当然,我会想创建至少一个盖当我创建一个漫画,其实这可能是一个业务规则。所以现在我卡住了,我要么强制客户端首先提交封面,得到了URI为掩护,然后过帐与URI的ComicBook在列表中执行业务规则,或者我对ComicBook POST发生在不同的期待资源比它吐出来。对于POST传入的资源和GET深拷贝,其中传出的GET包含对相关资源的引用。

Now I have a problem with creating new comics. Surely I'm going to want to create at least one cover when I create a Comic, in fact that's probably a business rule. So now I'm stuck, I either force the clients to enforce business rules by first submitting a Cover, getting the URI for that cover, then POSTing a ComicBook with that URI in the list, or my POST on ComicBook takes in a different looking Resource than it spits out. The incoming resources for POST and GET are deep copies, where the outgoing GETs contain references to dependent resources.

封面资源可能是在任何情况下,必要的,因为我相信作为一个客户我愿意地址在某些情况下盖的方向。因此,在一般的形式存在的问题不管从属资源的大小。一般来说,你如何处理复杂的资源而不强制客户端只是知道这些资源是如何构成的?

The Cover resource is probably necessary in any case because I'm sure as a client I'd want to address Covers direction in some cases. So the problem exists in a general form regardless of the size of the dependent resource. In general how do you handle complex Resources without forcing the client to just "know" how those resources are composed?

推荐答案

@ray,精彩讨论

@jgerman,不要忘了,只是因为它的休息,并不意味着资源必须在石头从POST设置。

@jgerman, don't forget that just because it's REST, doesn't mean resources have to be set in stone from POST.

您选择在资源的任何重新presentation包括什么是你来决定。

What you choose to include in any given representation of a resource is up to you.

您单独引用的盖的情况下,仅仅是一个父资源(连环画),其子资源(盖)可能是交叉引用的创建。例如,您可能也希望作者,出版者,字符或类别分别提供参考。你不妨单独或漫画书里面他们引用作为子资源之前创建这些资源。另外,您可能希望在创建父资源来创建新的子资源。

Your case of the the covers referenced separately is merely the creation of a parent resource (comic book) whose child resources (covers) may be cross-referenced. For example, you might also wish to provide references to authors, publishers , characters, or categories separately. You may wish to create these resources separately or before the comic book which references them as child resources. Alternatively, you may wish to create new child resources upon creation of the parent resource.

您的封面的特殊情况是在稍微复杂的封面确实需要一本漫画书,反之亦然。

Your specific case of the covers is slightly more complex in that a cover really does require a comic book, and visa versa.

然而,如果你考虑地址的电子邮件作为一种资源,而作为一个孩子的资源,可以很明显的仍然另附地址引用。例如,从地址获得所有。或者,创建与地址previous新的消息。如果邮件是REST,你可以很容易地看到,许多交叉引用的资源可以提供:/接收邮件,/草案的消息,/从-地址/到地址/地址/科目,/附件/文件夹,/标签/类别/标签等。

However, if you consider an email message as a resource, and the from address as a child resource, you can obviously still reference the from address separately. For example, get all from addresses. Or, create a new message with a previous from address. If email was REST, you could easily see that many cross-referenced resources could be available: /received-messages, /draft-messages, /from-addresses, /to-addresses, /addresses, /subjects, /attachments, /folders, /tags, /categories, /labels, et al.

本教程提供交叉引用资源的一个很好的例子。
<一href=\"http://www.peej.co.uk/articles/restfully-delicious.html\">http://www.peej.co.uk/articles/restfully-delicious.html

This tutorial provides a great example of cross-referenced resources. http://www.peej.co.uk/articles/restfully-delicious.html

这是自动生成的数据的最常见的模式。例如,你都不会发布URI,ID,或创建新的资源日期,因为这些都是由服务器生成。然而,你可以当你获得新的资源重新找回URI,ID或创建日期。

This is the most common pattern for automatically-generated data. For example, you don't post a URI, ID, or creation date for the new resource, as these are generated by the server. And yet, you can retrieve the URI, ID, or creation date when you get the new resource back.

在您的二进制数据的情况下的一个例子。例如,您要发布二进制数据作为子资源。当你父资源可以重新present这些子资源,为相同的二进制数据,或者作为重新present二进制数据的URI。

An example in your case of binary data. For example, you want to post binary data as child resources. When you get the parent resource you can represent those child resources as the same binary data, or as URIs which represent the binary data.

表格及放大器;参数已经比资源的HTML重新presentations不同。发布这导致URL二进制/文件参数不舒展。

Forms & parameters are already different than the HTML representations of the resources. Posting a binary/file parameter which results in a URL isn't a stretch.

当你得到一个新的资源的形式(/漫画书/新),或者获取表单编辑资源(/漫画书籍/ 0 /编辑),你所要求的一个具体形式,再$资源的对$ psentation。如果你把它发布到与资源集的内容类型应用程序/ x-WWW的形式urlen codeD或多部分/表单数据,你是要求服务器保存类型重新presentation 。服务器可以用HTML重新presentation这是保存,或任何回应。

When you get the form for a new resource (/comic-books/new), or get the form to edit a resource (/comic-books/0/edit), you are asking for a forms-specific representation of the resource. If you post it to the resource collection with content-type "application/x-www-form-urlencoded" or "multipart/form-data", you are asking the server to save that type representation. The server can respond with the HTML representation which was saved, or whatever.

您可能还希望允许的HTML,XML或JSON重新presention被张贴到资源集合,一个API或类似的目的。

You may want to also allow for an HTML, XML, or JSON represention to be posted to the resource collection, for purposes of an API or similar.

也可以重新present你的资源和工作流程为你描述,考虑到漫画书公布后罩帐户,但要求漫画书有一个盖子。示例如下:

It is also possible to represent your resources and workflow as you describe, taking into account covers posted after the comic book, but requiring comic books to have a cover. Example as follows.


  • 允许延迟封面创作

  • 允许与所需的封面
  • 漫画创作
  • 允许盖是交叉引用

  • 允许多个盖板

  • 创建草案漫画书

  • 创建草案漫画书籍封面

  • 发布的漫画书草案

GET /漫画书

=> 200 OK,获取所有的漫画书。

GET /comic-books
=> 200 OK, Get all comic books.

GET /漫画书籍/ 0

=> 200 OK,获取漫画书(ID:0)。有盖(/涵盖/ 1 /涵盖/ 2)

GET /comic-books/0
=> 200 OK, Get comic book (id: 0) with covers (/covers/1, /covers/2).

GET /漫画书籍/ 0 /涵盖

=> 200 OK,获取漫画书(ID:0)封面。

GET /comic-books/0/covers
=> 200 OK, Get covers for comic book (id: 0).

GET /涵盖

=> 200 OK,获取所有的盖子。

GET /covers
=> 200 OK, Get all covers.

GET /涵盖/ 1

=> 200 OK,找盖(ID:1),与漫画书(/漫画书籍/ 0)

GET /covers/1
=> 200 OK, Get cover (id: 1) with comic book (/comic-books/0).

GET /漫画书/新

=> 200 OK,获取表单创建漫画书(格式:POST /草稿漫画书)

GET /comic-books/new
=> 200 OK, Get form to create comic book (form: POST /draft-comic-books).

POST /草稿漫画书

名称= foo

笔者=嘘声

出版商=咕

出版= 2011-01-01

=> 302找到了,地点:/草稿漫画图书/ 3,重定向起草漫画书(ID:3)盖(二进制)

POST /draft-comic-books
title=foo
author=boo
publisher=goo
published=2011-01-01
=> 302 Found, Location: /draft-comic-books/3, Redirect to draft comic book (id: 3) with covers (binary).

GET /草稿漫画图书/ 3

=> 200 OK,获取草拟漫画书(ID:3)。有盖

GET /draft-comic-books/3
=> 200 OK, Get draft comic book (id: 3) with covers.

GET /草稿漫画图书/ 3 /涵盖

=> 200 OK,获取漫画草案书籍封面(/草稿漫画书/ 3)。

GET /draft-comic-books/3/covers
=> 200 OK, Get covers for draft comic book (/draft-comic-book/3).

GET /草稿漫画图书/ 3 /涵盖/新

=> 200 OK,获取的形式创造的漫画书草案盖(/草稿漫画书/ 3)。(格式:POST /草稿漫画图书/ 3 /套)

GET /draft-comic-books/3/covers/new
=> 200 OK, Get form to create cover for draft comic book (/draft-comic-book/3) (form: POST /draft-comic-books/3/covers).

POST /草稿漫画图书/ 3 /涵盖

cover_type =前

cover_data =(二进制)

=> 302找到了,地点:/草稿漫画图书/ 3 /套,重定向到新盖的漫画书草案(/草稿漫画书/ 3 /涵盖/ 1)

POST /draft-comic-books/3/covers
cover_type=front
cover_data=(binary)
=> 302 Found, Location: /draft-comic-books/3/covers, Redirect to new cover for draft comic book (/draft-comic-book/3/covers/1).

GET /草稿漫画图书/ 3 /发布

=> 200 OK,获取的形式出版的漫画书草案(ID:3)。(格式:POST /出版,漫画书)

GET /draft-comic-books/3/publish
=> 200 OK, Get form to publish draft comic book (id: 3) (form: POST /published-comic-books).

POST /出版,漫画书

名称= foo

笔者=嘘声

出版商=咕

出版= 2011-01-01

cover_type =前

cover_data =(二进制)

=> 302找到了,地点:/漫画书/ 3,重定向到出版的漫画书(ID:3)。有盖

POST /published-comic-books
title=foo
author=boo
publisher=goo
published=2011-01-01
cover_type=front
cover_data=(binary)
=> 302 Found, Location: /comic-books/3, Redirect to published comic book (id: 3) with covers.

这篇关于REST复杂/复合/嵌套资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆