IT:AD:REST

  • Stands for REpresentational State Transfer
  • Attributed to Roy Fielding's doctoral dissertation in 2000.
  • Six Constraints:
    • Client/Server
      • SOC: Client doesn't concern itself with storage, etc.
    • Stateless.
      • No server state. Only Client State.
    • Cacheable
      • Clients can cache resources, per server' instructions on its staleness.
    • Layered system
    • Code on demand (optional)
    • Uniform interface; resource identifier (e.g URL) , methods (e.g. GET, POST), media types (e.g. XML, JSON)
  • -

The crux of it all is mostly:

  • HTTP already defines Verbs: GET|PUT|POST|DELETE, etc.
  • Whereas RPC, WCF, etc. encourage the invention of arbitrary Operation names (getUsers(), saveNewUser(), deleteUser(x), (both of which are using POST, rather than POST and DELETE….)
  • This additive operations name is reinventing is the issue. Instead of inventing arbitrary names, change the method.

Therefore, move your Operation Names out of the Url, and move them to the Http Verb.

COMMON MISTAKE: do not confuse with Http Form POST verb, which is used to process data as seen, as not RESTful.

  • REST is an architecture, not a protocol (like SOAP).
  • So it doesn't dictate XML|JSON|etc.
  • Content-Negotiation is generally handled via Accepts header.

Support PUT and DELETE:

  • Desktop:
    • IE7+ (notably, IE6 = NO)
    • FF3+
    • Safari
    • Opera
  • Mobile
  • -

There's often a common miscomprehension that

http://localhost/client/1002/invoice/13 is a RESTful url. It isn't. It's just a friendly url.

What makes it RESTful is:

 0. unique resource url, and 
 0. the changing of the VERB.

Urls in REST are unique addresses of Resources. If they are friendly/pretty, that's all the better.

Resources are usually Domain objects.

Then again, maybe those friendly urls could be expressed as :

Hum…

The resource ids are urls, which are are unique network (read “server”, above) resource identifiers, that hide implementation.

In other words, an Invoice Domain Entity may have a unique DBMS Identifier of

12 (an implementation issue), 

but that is not to be confused with the unique Network Identifier:

`http://localhost/client/234/invoice/123`

Note: A check is that we do not talk about INVOICE 123, but about RESOURCE http://localhost/client/234/invoice/123

  • As per HTTP 1.1 specification, GET, HEAD, PUT and DELETE are idempotent, POST is not.
  • You can repeat the Idempotent operations (HEAD, GET, PUT, and DELETE) over and over again, and you get back the same results.
  • POST you cannot.
    • Hence why when the browser, when you back up/forward prompts with a warning before resubmitting the post.
  • -

Retrieve: GET

  • List:
    • http://localhost/client/234/invoice/
    • http://localhost/client/234/invoice/page/3/
    • http://localhost/client/234/invoice/page/3/records/20
    • http://localhost/client/234/invoice/16-24
    • http://localhost/client/234/invoice/16/to/24
    • http://localhost/client/234/invoice/id/16/to/24
    • http://localhost/client/234/invoice/date/gt/2010-01-01
    • etc.
  • Item:
    • http://localhost/client/234/invoice/112
  • Responses:

Create: POST

Same as GET but just headers.

Update: PUT

  • List:
    • Update a range of records with common settings.
  • Item:
    • Update a single record.
      • Convention is that it creates a record at the Id, if none exists. But throw an Exception.
    • http://localhost/client/234/invoice/112
      • Note: creates a new one with given id, or replaces existing one.
  • Response:
    • HTTP 200 (OK), with content depending on the method, or
    • HTTP 202 (Accepted)
    • HTTP 201 (Created). Maybe…but I wouldn't recommend this as it obfuscates POST mechanism.
    • HTTP 204 (No Content) Resource Updated Successfully.
    • HTTP 304 (Content not Modified). No changes?
    • HTTP 401 Unauthorized (ie, Not Authenticated). See why: http://stackoverflow.com/a/6937030/1052767
    • HTTP 403 Forbidden (ie, Not Authorized). See why: http://stackoverflow.com/a/6937030/1052767
    • HTTP 404 (Not found) . No record to update.

Delete: DELETE

  • List:
    • Delete a range of Records
    • http://localhost/client/234/invoice/date/lt/2010-01-01
    • etc.
  • Item:
    • http://localhost/client/234/invoice/112
    • HTTP 200 (OK), with content depending on the method, or
    • HTTP 202 (Accepted) could be used to imply 'marked for deletion', or
    • HTTP 204 (No Content) Resource Updated Successfully.
    • HTTP 401 Unauthorized (ie, Not Authenticated). See why: http://stackoverflow.com/a/6937030/1052767
    • HTTP 403 Forbidden (ie, Not Authorized). See why: http://stackoverflow.com/a/6937030/1052767
    • HTTP 404 Resource not found.

After POSTing a new record to http://localhost/invoice/ (ie, Create), the server sends back a Redirect code of 302, which tells the browser to GET the new invoice at http://localhost/invoice/1023

PUT doesn't need the same method as the invoice id is in the url.

  • REST is Stateless.
    • Therefore, authentication has to be sent each and every time (unlike straight WCF, which could have State if so desired).
  • If the operation is suppossed to leave you always in the same state, what does doubling a DELETE do? Error second time? Say fine again?
    • It's not a Browser request, so doesn't need a page response, just an Ack code.
  • Not sure if DELETE should redirect to the the list.
    • Same: It's not a Browser request, so doesn't need a page response, just an Ack code.

Where REST is not that great is batch changes.

Examples might be:

  • Update the Status of all Students Where Age < 14

You have to think of the UpdateStudentStatus Operation as a StudentStatusUpdate Resource that can only be PUT'ed with a StudentStatusUpdate object (the filter). I agree it's less intuitive and verbose. But it is also specific, and fits well into SOC Principles.