RESTful HTTP Notes by Pierre Chapuis , 2009-08 Most of the following is based on: RESTful Design, Patterns and Anti-Patterns, Stefan Tilkov http://www.parleys.com/d/1397 # Principles - use as many URIs and URLs as possible - respect HTTP specification - multiple representations for resources - stateless communications ## HTTP Specification ### GET Retrieve information - safely: doesn't have any negative effect for the user; - efficiently: caching is possible. ### HEAD Same as GET without a response body, not very useful except if the GET body is supposed to be very big. ### PUT Create of update a resource at a given, known URI. ### POST Create or append a sub-resource. ### DELETE Delete something. ### OPTIONS Retrieve available methods: built-in discovery. Ex. response: Allow: GET, POST ### Idempotence GET, PUT and DELETE are idempotent: they can be safely retried. POST is *not*. ### HTTP seen as an interface to implement interface Resource { Resource(URI u) Response get() Response post(Request r) Response put(Request r) Response delete() } => Generic way to expose things, specific solution in implementation. There can be intermediate classes: HTTP <- ATOM <- MyFeed ## Multiple Representations Get /p/123 Host: cw.com Accept: application/xhtml+xml Get /p/123 Host: cw.com Accept: text/x-vcard => Same URL, same content but different formats. ## Stateless Communications Never keep client session state on server side. Usually, use URIs instead! # Anti-Patterns (not-RESTful) ## Tunnel everything over GET http://ex.com/myapi?method=insert&name=Smith By the way, what happens if Google follows this link? ## Tunnel everything over POST For example: SOAP! POST http://ex.com/myapi 42 PBs: - deleteItem is a method - the ID is not a URI - http://ex.com/myapi is an endpoint: need for a specific client to use it Web Services are *not* on the web (protocol independence is stupid, port 80 is open is not a good reason). ## Ignore Caching ETags: made to identify the state of a resource => allows caching, enables the Web to scale. ## Ignore Response Codes 404: NOT FOUND, not "Internal Server Error" Useful: 410 Gone, 409 Conflict... ## Misuse Cookies BAD if it identifies an in-memory state. It is possible to use RESTful cookies, but HTTP Authentication is usually better. ## application/xml Using a "application/xml" MIME type means "this is a *thing*" and is not very useful. It is a kind of tunneling. "application/cw.mytype" is better but too specific, it is much better to use something intermediate such as ATOM, XHTML... # RESTful Patterns See the video for more on: - Collection Resource: list of things - Paged Collection: same but for big lists, eg. index items 1-20 and link to the others - Read-only View: different representations for a list; filtering based on URIs - Resource Creation: POST -> 201 Possibly Changed + Location header - Resource Creation 2 (if idempotence needed): POST -> URI; PUT URI - Named Links: the type of a link describes its content's type. It allows specific clients to work without understanding everything. - Very complex searchs (long text): POST query -> URI, GET URI. - Transaction: modify several resources in a single request. To do that, turn the transaction into a resource and use PUT. # Tips ## Stop worrying about URIs Good URIs (meaningful) are good but don't matte much, links are more important. Use polling for notifications (with ETags -> 304 usually), like RSS/ATOM. It often scales more than PUSH. Use 409/412 for conflict handling. Use Conneg Extensions: http://ex.com/p/123 <- type negotiation http://ex.com/p/123.txt http://ex.com/p/123.xml If a firewall blocks PUT/DELETE for bad reasons, tunnel them over POST. Have canonical representations on URLs: text-based (eg. HTML) for content, forms for methods.