8. REST Architecture Components

Key components of a REST architecture:

  • Resources, which are identified by logical URLs. Both state and functionality are represented using resources.
    • The logical URLs imply that the resources are universally addressable by other parts of the system.
    • Resources are the key element of a true RESTful design, as opposed to "methods" or "services" used in RPC and SOAP Web Services, respectively. You do not issue a "getProductName" and then a "getProductPrice" RPC calls in REST; rather, you view the product data as a resource -- and this resource should contain all the required information (or links to it).
  • A web of resources, meaning that a single resource should not be overwhelmingly large and contain too fine-grained details. Whenever relevant, a resource should contain links to additional information -- just as in web pages.
  • The system has a client-server, but of course one component's server can be another component's client.
  • There is no connection state; interaction is stateless (although the servers and resources can of course be stateful). Each new request should carry all the information required to complete it, and must not rely on previous interactions with the same client.
  • Resources should be cachable whenever possible (with an expiration date/time). The protocol must allow the server to explicitly specify which resources may be cached, and for how long.
    • Since HTTP is universally used as the REST protocol, the HTTP cache-control headers are used for this purpose.
    • Clients must respect the server's cache specification for each resource.
  • Proxy servers can be used as part of the architecture, to improve performance and scalability. Any standard HTTP proxy can be used.

Note that your application can use REST services (as a client) without being a REST architecture by itself; e.g., a single-machine, non-REST program can access 3rd-party REST services.

14 comments:

Dr. M. Elkstein said...

While SOAP Web Services also runs on top of HTTP, most SOAP implementations ignore HTTP caching instructions. As a result, REST is often far superior to SOAP in terms of performance.

Dr. M. Elkstein said...

Working correctly with resources and links means that, on the one hand, there are no multiple fine-grained requests (as is common in RPC designs -- this was the downfall of EJB 1.x a long time ago); and on the other hand, the responses need not be huge and contain everything. A link to additional data, in case the extra data is large, means that servers can reply quickly and there's no traffic overhead for un-needed data. (Contrast that with the bloat the is so common to SOAP applications.)

All this implies, again, that REST is often more efficient than competing designs.

Fredrik said...

Hi and thank you for providing this tutorial.

"Each new request should carry all the information required to complete it, and must not rely on previous interactions with the same client."

How do you handle authorization with REST? Would you still have the user log in once set the rights in the session and then check the session for subsequent calls? Sounds like the rule prompts sending even the login info with each request.

Fredrik said...

Whenever relevant, a resource should contain links to additional information

Could you explain how this links work? You mean a specific response telling the client f.x the response body is to big and the request needs to be fine-tuned? And then what? how are links used in all this?

Dr. M. Elkstein said...

Hello fliden,

Two answers for your two questions.

1. Authorization: There are two common ways to do it.
a. Provide a login REST service, which accepts a username and password, and returns a token. This token expires after a predefined time (optionally, every use of the token refreshes it; so a token used on a regular basis never expires). Now, every additional request can include the token as one of its arguments.
b. Use cookies. The cookies can include the actual username and password with every request, or a token. (If using a token, again you need to define a login request to generate this token).

Many people dislike the cookies-based approach, since it complicates the request-sending, and the request contains more than meets the eye (i.e., more than just the URL).

2. For an example of using URLs in responses, see the next page in this tutorial.

Kosta Kontos said...

Hi Dr Elkstein

Firstly, thank you for an excellent tuorial on REST; it is easily the best I've come across.

Secondly, could you please elaborate on the token-based authorisation technique in the context of the PHP Session API? Any additional insight into how the Login REST service is implemented would also be appreciated.

Cheers from South Africa.

Dr. M. Elkstein said...

Hello Kosta,

To use the PHP session API, your client must support cookies. If it does, you're practically done: the very existence of the session cookie indicates that this is the same client. So once the client logs in, keep this knowledge (e.g., the login start time) as part of his session data.

Note that I assume the PHP session API uses a safe, unguessable cookie value to identify the session. If you don't trust it, I believe you can change the function that generates the session cookie values.

Justicle said...

"Resources should be cachable whenever possible"

Can you give an example of this? Who does the caching.

Thanks!

Dr. M. Elkstein said...

Hello Justin,

Caching is done according to the HTTP standard. This means the client can (if it wishes) cache results, but he must respect the HTTP cache control headers. These headers can specify, for example, an "expiration time" for each result; the result should be flushed from the cache after that time. Also, the HTTP headers can specify that specific results must not be cached -- this should be used for items that change constantly.

pavan said...

Dear Dr.Elkstein,

'Proxy servers can be used as part of the architecture, to improve performance and scalability. Any standard HTTP proxy can be used."

Bit confused here...

Camaromelt said...

In section 8 you spelled Clients Cilents. Just wanted to let you know incase you wanted to fix it. Thanks for the awesome tutorial.

Dr. M. Elkstein said...

Camaromelt -- I fixed that now. Thanks!

Unknown said...

Hi,

Can you please elaborate on "one component's server can be another component's client"

Thanks,
VN

Dr. M. Elkstein said...

Hi Vinu,

When you provide a service, it can use a different service in order to do its thing. For example, let's say I have a REST server with an API that accepts an address and returns longitude and latitude for this address. Another REST server accepts a person name and provides information about that person (via database lookup), including a link to a map; the map uses lon/lat coordinates as input. So, the second service (person lookup) uses the first service (lon/lat lookup). The second service is a server for you, but a client for the first service.