Everyone wants to make a RESTful web service these days. But
REST is much more than naming resources with nouns and just not doing SOAP.
REST, or Representational State Transfer, is an architectural style
for distributed systems defining certain constraints that provide
efficiency, scalabilty, and other desirable attributes.
REST was introduced
by Roy Fielding. The constraints he identified were:
- Client-Server — separates UI from data storage
- Stateless Server — improves reliability and scalability
- Client Cache — reduces some network traffic
- Uniform Interface — decouples implementations from the services they provide
- Layered System — means that each component only be concerned with those just below or just above it
- Code-on-Demand — allows client functionality to be extended by downloading applets or scripts
REST is an architectural style, NOT a product, NOT an API.
The World Wide Web is an example of a RESTful system.
Principles of REST
A RESTful system is characterized by
- Addressable Resources
- Every resource has a (unique) identifier (e.g., URI)
- Resources are generally nouns. Name your resources accordingly:
- Resources are separate from their representations
- Requests for resources return representations
- The representation contains the state of the resource
- The client can update or delete resources through their representations
- Uniform, Constrained Interface
- Small, fixed number of verbs
- Example: In HTTP, GET, PUT, POST, DELETE, HEAD, OPTIONS, TRACE only!
- Non-example: Any RPC-based protocol such as SOAP or CORBA
- Self-Descriptive Messages
- Messages include all the information necessary to be processed
- Example: Internet Media Types
- Stateless Server
- With no shared context on the server, client requests are independent
- Servers can be simpler, "more" multithreaded, easier to monitor, reliable, scalable, etc.
- Responses indicate whether the client can cache the data or not
- Reduces network traffic if the client knows it doesn't have to ask for the same data again
- Hypermedia as the engine of application state
- Representations should include links to related resources
- Reduces the need for versioning by making most resources discoverable only from other resources
Writing RESTful Web Services
- Remember when OOP was new?
- You had to shift your thinking from procedures to objects (from verbs to nouns): QueryOptimizer, ImageMapper, SiteInitializer, StringTokenizer, Enumerator, StreamReader, StreamWriter, Factory
- Transitioning from RPC to REST is the same thing!
- Think: what are my resources?
- Examples: products, campaigns, customers, listings, profiles, lists, reviews, ads
- Resources do not have to be finely-grained. They do not have to correspond exactly to database tables.
- Dealing with limited number of verbs
- Solution: Capture semantics with more resources (consider resource hierarchy)
- Commands, events, and actions can be resources too (but don't overdo this)
RESTful and non-RESTful URIs
Use a framework
If you are writing a webapp back-end, you most certainly are using some kind of server-side
Ruby, a .NET backend, or plain old PHP. Many of these products have a mechanism for "doing
REST". For Java, you can use a JAX-RS implementation such as Jersey, RestEasy, or CXF.
REST and HTTP
HTTP is a stateless request-response protocol
Using HTTP Methods RESTfully
|Get all things. Use query parameters to restrict set or paginate.
|Replace the set of all things. Put set in payload.
|Create a new thing. Server sets id. Put representation of new thing in payload.
|Delete all of the things.
|Get thing 8.
|Replace thing 8 with new thing, but id stays 8. Put representation in payload. Or create a new thing with id 8.
|If thing 8 is a collection, create a new item in this collection with server generated id.
|Delete thing 8.
You can implement OPTIONS yourself, too. HEAD will pretty much be handled by a framework.
Respect method constraints:
- GET and HEAD should be safe (no user-requested resource modifications)
- GET, HEAD, PUT, and DELETE should be idempotent (repeated requests same as one)
HTTP Request Headers
There are many request headers but the one you might use most frequently is the
header. To request that the server give you a representation in a desired format, supply a header
Use response codes as they were intended to be used. The ones you should
be aware of (that is, that you may set yourself as part of your application) are:
|405||Method Not Allowed (service doesn't support the requested method at that URI)
|406||Not Acceptable (server can't give back a representation in a requested format)
|415||Unsupported Media Type (server can't process the request body)
|201||Created (usually you should set the Location header for this)
|202||Accepted (used for asynch requests)
HTTP Response Headers
You will probably set
A framework will do the others.