10

我是 REST 架构设计的新手,但我认为我已经掌握了它的基础知识。

我从 RESTful 调用返回对象时遇到问题。如果我发出诸如http://localhost/ {type A}/{id} 之类的请求,我将从数据库中返回一个具有指定 ID 的 A 实例。

我的问题是当 A 包含 B 对象的集合时会发生什么?目前,我生成的 XML 返回 A,其中包含 B 对象的集合。可以想象,如果 B 类型有一个 C 对象的集合,那么返回的 XML 最终将是一个相当复杂的对象图。

我不能 100% 确定,但这感觉违反了 RESTful 原则,A 的 XML 应该将 A 的字段等以及 URI 的集合返回到它拥有的 B 的集合。

抱歉,如果这有点令人困惑,我可以尝试详细说明。这似乎是一个相对基本的问题,但是我无法确定哪种方法“更”RESTful。

干杯,

艾多斯

4

3 回答 3

10

一个基本的 RESTful 原则是一切都有一个 URI。

你有这样的URI。

  • /A/ and /A/id/ to get a list of A's and a specific A. The A response includes the ID's of B's.
  • /B/ and /B/id/ to get a list of B's and a specific B. The B response includes the ID's of C's.
  • /C/ and /C/id/ to get a list of C's and a specific C.

You can, through a series of queries, rebuild the A-B-C structure. You get the A, then get the relevant B's. When getting a B, you get the various C's that are referenced.


Edit

Nothing prevents you from returning more.

For example, you might have the following kinds of URI's.

  • /flat/A/id/, /flat/B/id/ and /flat/C/id/ to return "flat" (i.e., no depth) structures.

  • /deep/A/id/, /deep/B/id/ and /deep/C/id/ to return structures with complete depth.

The /deep/A/id/ would be the entire structure, in a big, nested XML document. Fine for clients that can handle it. /flat/A/id/ would be just the top level in a flat document. Best for clients that can't handle depth.

于 2008-12-23T02:41:26.593 回答
5

没有什么说你的 REST 接口不能是相关的。

  1. /书店/ {书店ID}
  2. /bookstore/ {bookstoreID} /books
  3. /book/ {bookID}

基本上,您与您的数据库模式有 1:1 的对应关系。

除了形成子列表的多对多关系。例如,/bookstore/657/books 应该返回书籍 ID 或 URL 的列表。然后,如果您想要特定书籍的数据,您可以调用第三个 URL。

这只是我的想法,请辩论是非曲直。

于 2008-12-23T01:54:22.490 回答
-1

Make a flat Universe that you expose to the world.

Even when I use SOAP, which can easily handle hierarchical object graphs up to whatever depth, I flatten the graph and link everything with simple IDs (you could even use your database IDs, although the idea is that you want you don't want to expose your PKs to the world).

Your object universe inside your app is not necessarily the same one you expose to the world. Let A have children and let B have children, but there's no need to reflect that in the REST request URLs.

Why flatten? Because then you can do things like fetch the objects later by ID, or send them in bursts (both the same case, more or less)... And better than all that, the request URIs don't change when the object hierarchy changes (object 37252 is always the same, even when it's been reclassed).

Edit: Well, you asked for it... Here's the architecture I ended up using: package: server - contains the superclasses that are shared between the front-end server and the back-end server

package: frontEndServer - contains a Server interface which the front-end server must adhere to. The interface is nice because if you decide to change from SOAP to a straight Web client (that uses JSON or whatever, as well), you've got the interface all laid out. It also contains all the implementations for the frontEnd classes that will be tossed to the client, and all the logic for the interaction between classes except how to talk to the client.

package: backEndServer - contains a Server interface which the back-end server will adhere to. An example of a Server implementation would be one that talks to a MySql DB or one that talks to an XML DB, but the Server interface is neutral. This package also contains all the classes that the implementations of the Server interface use to get work done, and all the logic for the backend except for persistence.

then you have implementation packages for each of these... which include stuff like how to persist for the backend and how to talk to the client for the front end. The front-end implementation package might know, for instance, that a user has logged in, whereas the frontEndServer just knows that it has to implement methods for creating users and logging in.

After beginning to write this up I realize that it would take a while more to describe everything, but here you have the gist of it.

于 2008-12-23T06:29:03.420 回答