9. REST Design Guidelines

Some soft guidelines for designing a REST architecture:

  1. Do not use "physical" URLs. A physical URL points at something physical -- e.g., an XML file: "http://www.acme.com/inventory/product003.xml". A logical URL does not imply a physical file: "http://www.acme.com/inventory/product/003".
    • Sure, even with the .xml extension, the content could be dynamically generated. But it should be "humanly visible" that the URL is logical and not physical.
  2. Queries should not return an overload of data. If needed, provide a paging mechanism. For example, a "product list" GET request should return the first n products (e.g., the first 10), with next/prev links.
  3. Even though the REST response can be anything, make sure it's well documented, and do not change the output format lightly (since it will break existing clients).
    • Remember, even if the output is human-readable, your clients aren't human users.
    • If the output is in XML, make sure you document it with a schema or a DTD.
  4. Rather than letting clients construct URLs for additional actions, include the actual URLs with REST responses. For example, a "product list" request could return an ID per product, and the specification says that you should use http://www.acme.com/product/PRODUCT_ID to get additional details. That's bad design. Rather, the response should include the actual URL with each item: http://www.acme.com/product/001263, etc.
    • Yes, this means that the output is larger. But it also means that you can easily direct clients to new URLs as needed, without requiring a change in client code.
  5. GET access requests should never cause a state change. Anything that changes the server state should be a POST request (or other HTTP verbs, such as DELETE).

19 comments:

David F said...

Including the actual URLs with REST responses seems a good idea. However, how can we design a universal data model that can be used for web services in a SOA world AND be used with a REST application in a ROA world.

Dr. M. Elkstein said...

Hi David,

The data model has to be the same. The way you expose it to the world (the "view") should be independent of the model code, and you can have different views (e.g., a SOAP view and a REST view) for the same model.

Mike Schinkel said...

I disagree with #1. I believe it's evolving as a best practice to map extensions to response content types.

The mapping is documented by the server, NOT something that is part of the HTTP spec, i.e. you can't assume the mapping to be true unless the server documents it to be so. One server may choose to map .xml to 'text/xml' whereas another may choose to map it to 'application/xml'. However the use cases where there isn't an obvious 1-to-1 mapping are rare.

Mapping extensions to response content types makes it a lot easier for the developer to switch content types and, for that matter, to understand how to use the service.

Dr. M. Elkstein said...

Hi Mike,

That's a valid and interesting point, esp. given the advice I give in guideline #3 above. Thanks!

സുല്‍ത്താന്‍ said...

Dear Dr. M. Elkstein,

Thank you for your tutorial. I am started writing rest apis for my content management system. But I can only able to write the physical urls. Like http://localhost/restwebservice/rest/women.json. I am using php to write my rest apis. Can you please tell me how can I write an api without file name. http://localhost/restwebservice/rest/women

Dr. M. Elkstein said...

Hi സുല്‍ത്താന്‍,

This really depends on your software stack. For example, if you're using Apache, you can use rewrite rules to achieve this effect.

ahsan said...

Hi Mike,
i couldn't understand ur point no 3 i.e. "your clients are not human". What do u mean by that.

if i am developing a management system where there will be user operators to perform different actions like create a new project and select a team from resources available in a database. plus algo to grade performance

can i do this using rest
thanks

Dr. M. Elkstein said...

Hello ahsan,

(My name is not Mike.) What you're describing is the development of a standard website.

ahsan said...

Dr. M. Elkstein

yes what i am trying to develop is a web based applicatioon but what i intend is that i establish services i.e. like login/registeration service,resource publication service, performance grading etc.
and the client web based i.e. jsp app to acquire/call these services

Dr. M. Elkstein said...

Hello ahsan,

Yes, you can obviously use REST for that.

Nyro said...

Regarding the url including for every listed element: what do you think about including the root url (like site.com/product/).in the response and then indicating to the developer how he should construct it using the id in the list (a simple concaténation for instance)

Dr. M. Elkstein said...

Hello Nyro,

I believe guideline #4 in the list above clearly answers your query: No, you should not direct clients to build their own URL; whenever possible, always provide an explicit URL.

Bajal said...

Sorry for a dumb newbie question. But how does #4 increase response size?

BTW, Great introduction to REST.

Daniel Nordstrom said...

Bajal,

A response that contains a numeric ID (1234) will be smaller than a response containing a whole URI (http://example.com/product/1234).

Kamlekar Venkateshwar said...

The ad at middle-left is obscene. which is troubling me from reading your blog in my office :). I hope you will care that..

Kamlekar Venkateshwar said...
This comment has been removed by the author.
Lingxiao Wu said...

#2 For example, a "product list" GET request should return the first n products (e.g., the first 10), with next/prev links.

isn't using "next/prev" link makes the request stateful?

Dr. M. Elkstein said...

Hi Lingxiao,

No, adding these links does not make the request stateful. The "next" link, for example, will contain a "start from" index. So the next request, still stateless, simply indicates that the list should start from a given index rather than from index 0.

Sony Thomas said...

Can I configure in spring application context.xml a timeout value for the rest service?