1

I am implementing a REST web service and I'm wondering if there is any convention on how should information exposed by the service be atomized. So far I've been unable to find a satisfactory solution so now I'm asking to the greatest minds ever found in the Internet :P

For example, let's suppose I want to implement an API to access to some sort of library registry, so we have a resource with path /books. By reading /books/123 we would get, for instance, the XML data below:

<?xml version="1.0" encoding="utf-8"?>
<book>
    <title>Visit Catalonia</title>
    <author>J. Hans</author>
    <year>2000</year>
</book>

Imagine the author information were wrong and I wanted to change it thru the web service's API. I come up with two possible options, each one with advantages and drawbacks:

OPTION 1: Issue a HTTP PUT method to /books/123 with the data below:

<?xml version="1.0" encoding="utf-8"?>
<book>
    <author>G. Robinson</author>        
</book>

Advantages:

  • It's only necessary to implement 1 resource handler: /books/BOOKID
  • We can modify as many pieces of information as XML tags are defined in the data (e.g.: adding in the code above we would update the book's year too).

Drawbacks:

  • GET method always returns all data about a book; we cannot access just a single piece of information. In this example getting all data is not an issue, but what if /book/123 also had a tag with the book's content itself in order to read it online?

OPTION 2: Issue a HTTP PUT method to /books/123/author sending the data:

<?xml version="1.0" encoding="utf-8"?>
<author>G. Robinson</author>

Advantages:

  • Information can be accessed in an arbitrary level of depth: the API client can just download the piece of information he/she needs.

Drawbacks:

  • We can't get or modify several pieces of information with a single HTTP request.
  • Implementation is tough: as many subresources as information fields.

So, summarizing, my question is if there's any commonly accepted convention to expose information in a web service. Of course, in simple web services that manage little amount of data this is not an issue, but what if we are exposing a real world database?

Thank you very much in advance.

4

2 回答 2

2

Remote interfaces (like webservices) are usually coarsely grained. This minimizes network overhead.

Issueing a HTTP PUT to /books/123 with the data

<?xml version="1.0" encoding="utf-8"?>
<book>
    <author>G. Robinson</author>        
</book>

seems to me like the book does not have a <title> and a <year> anymore. Data that you PUT to /books/123 should include all relevant information about the book, even the ones that did not change.

Issuing a HTTP PUT to /books/123/author with data

<?xml version="1.0" encoding="utf-8"?>
<author>G. Robinson</author>

is the kind of finely grained control that you would expect from a local interface, not a remote interface. Use this in addition to the coarsly grained interface if updating the whole book data at once with the coarsly grained interface is prohibitively expensive (e.g. if the book data also contains the full text of the book and you frequently need to update only a single property).

于 2013-10-20T08:02:46.847 回答
1

I believe you can have both, depending on the client needs/situation you want to support:

  • GET/POST /books/123 : you get and post (create/update) the complete book properties
  • GET/POST /books/123/author : you get and post (create/update) the author of the book

there is no reason why you couldn't use both options. The clients can follow one or the other depending on the situation they are... Option 1 seems to be more appropriate when creating new book entries, or updating the whole entry... whereas option 2 if you in the client UI allow to update "one property" at a time. So, this may very much depend on the client "intents"/situations you want to support... You should take that into consideration when making your design.

I have just read a nice article on InfoQ that touched some of these points (among other things). Take a look at "don't expose your domain model" and "design your API based on intent" points - http://www.infoq.com/news/2013/10/gotober-do-dont-webapi.

于 2013-10-20T08:16:42.673 回答