For more information see www.bbd.co.za and www.drp.co.za
Understanding REST and designing for it
Acronym?
Representational State Transfer
Source?
Came about in 2000 doctoral dissertation of Roy Fielding
ROA – Resource Orientated ArchitectureWOA – Web Orientated Architecture Thanks Gartner for another TLA It is a styleNOT API Interface Official Standard A drop in replacement for SOAP
Highly scalable
Designed for HTTP
Easy to consume & produce
No complex request/response model.
No complex XML contracts
Easy to understand for you and machines
URI + Method = Intent
REST builds on HTTP so you need to know HTTPHTTP is not HTMLHTTP is stateless
HTTP
Header
Body
URI
Method
Status Code
http://www.sadev.co.za
GET
200
text
Content Type text/plain
http://www.sadev.co.za/users/1/contact
http://www.sadev.co.za?user=1&action=contact
http://rob:[email protected]:8044
https://bbd.co.za/index.html#about
Scheme
Scheme
Scheme
Scheme
Hostname
Hostname
Hostname
Hostname
Query
Query
Query
Port
Fragment
Userinfo
HEAD Safe Gets just the HTTP header
GET Safe Gets HTTP head & body
POST Submits data in the body to the server
PUT Uploads a resource
DELETE Deletes a resource
TRACE Safe Echo’s back the request
OPTIONS Safe Gets a list of supported methods
CONNECT Safe Converts to a TCP/IP tunnel for HTTPS
PATCH Apply partial modifications to a resource
Just a guide
1xx – Informational
2xx – Success
3xx – Redirection
4xx – Client Error
5xx – Server Error
100 = Continue102 = Processing200 = OK201 = Created204 = No Content206 = Partial Content301 = Moved Permanently 302 = Found (Moved Temp)307 = Temp Redirect400 = Bad Request401 = Unauthorised
402 = Payment Required403 = Forbidden404 = Not Found405 = Method Not Allowed409 = Conflict418 = I’m a teapot450 = Blocked by Windows Parental Controls500 = Internal Server Error501 = Not Implemented
Proper name: Internet Media Type
Also known as MIME type
Parts: Type, SubType, Optional Parameters
x- prefix for nonstandard types or subtypes
vnd. prefix for vendor specific subtypes
Frowned upon by purists
text/plain – Plain texttext/xml – XML text/html – HTML image/png – PNG imageaudio/basic – Wave audioaudio/mpeg – MPEG audio (MP3)video/quicktime – Quicktime Videoapplication/pdf – Adobe PDF documentapplication/javascript – JavaScriptapplication/vnd.ms-powerpoint – PowerPoint fileapplication/x-rar-compressed – RAR file
Basic AuthenticationEasy to do, but plain text. Easy to reverse engineer. Less
of an issue when used with SSL.Digest AuthenticationHarder to do, still plain text. Hard (impossible?) to
reverse engineer because of hashing. NTLM AuthenticationHard to do, Windows specific. Hard (impossible?) to
reverse engineer.
HEAD /index.html
HTTP/1.1
Host: www.example.com HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Etag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Content-Length: 438
Connection: close
Content-Type: text/html; charset=UTF-8
Request
Response
A simple system to store what LEGO’s a person owns. Want toAdd bricks Set bricks status to be in useRemove bricksGet list of bricksCheck if I have enough bricksGet picture of brick
Action URI Method Content Type Input
Add https://lc/add POST n/a Request Body
Set status https://lc/update PUT n/a Request Body
Remove https://lc/remove DELETE n/a Request Body
Get list https://lc/list GET text/xml
Validate https://lc/validate GET text/plain
Get Picture https://lc/picture GET image/png Request Body
HTTP ValidREST ValidIntent good
Action URI Method Content Type Input
Add https://lc/add POST n/a Request Body
Set status https://lc/update/1 PATCH n/a URI + Request Body
Remove https://lc/remove/2 DELETE n/a URI
Get list https://lc/list GET text/xml
Validate https://lc/validate GET text/plain
Get Picture https://lc/picture/1 GET image/png URI
HTTP ValidREST ValidIntent good
Action URI Method Content Type Input
Add https://lc/add POST text/plain Request Body
Set status https://lc/update/1 PATCH text/plain Request Body
Remove https://lc/remove/2 DELETE text/plain Request Body
Get list https://lc/list GET text/xml
Validate https://lc/validate GET text/plain
Get Picture https://lc/picture/1 GET image/jpg URI
HTTP ValidREST ValidIntent good
Action URI Method Content Type Input
Add https://lc?a=c GET n/a Request Body
Set status https://lc?a=u GET n/a Request Body
Remove https://lc?a=d GET n/a Request Body
Get list https://lc?a=s GET text/xml
Validate https://lc?a=v GET text/plain
Get Picture https://lc?a=p GET image/png Request Body
HTTP ValidREST InvalidIntent bad
Action URI Method Content Type Input
Add https://u:p@lc:80?1 MAGIC n/a Request Body
Set status https://u:p@lc:80?2 MAGIC n/a Request Body
Remove https://u:p@lc:80?3 MAGIC n/a Request Body
Get list https://u:p@lc:80?4 MAGIC text/xml
Validate https://u:p@lc:80?5 MAGIC text/plain
Get Picture https://u:p@lc:80?6 MAGIC image/png Request Body
HTTP ValidREST InvalidIntent nightmare
Resource: Photos
Where:http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}.jpg
http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}_[mstb].jpg
http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{o-secret}_o.(jpg|gif|png)
What: JPEG, GIF or PNG (defined in the URL)
http://farm1.static.flickr.com/2/1418878_1e92283336_m.jpg
REST CRUD
POST Create
GET Read
PUT Update or Create
DELETE Delete
“The big four”
Accidental services do not use all methods
Some URL’s offering all of them and others a limited set
http://bbddb01/northwind/users[firstname=“rob%”]
+ POST = Error
+ GET = Returns everyone who begins with rob
+ PUT = Error
+ DELETE = Deletes everyone who begins with rob
http://bbddb01/northwind/users
+ we add some input data
+ POST = Creates a new user
+ GET = Returns everyone who meets criteria
+ PUT = Creates/Updates a user (based on data)
+ DELETE = Deletes everyone who meets criteria
http://bbddb01/northwind/users[firstname=“rob%”]
+ POST = Error
+ PUT = Error
What would the error be?
HTTP 400 would be best
405 or 500 could also be appropriate
GetStoreOpenTime(Location) GET http://lc/stores/{location}/times?state=open
RejectDesign(Design) POST http://lc/rejections + form data
PerformBrickCount(Design) POST http://lc/design/124/brickCount
GET http://lc/design/124/brickCount/2
Design to be stateless
Design for resources, not services
Stock quote service vs. A way to work with stock resources
Use cookies for self-contained state
Naming: Favour nouns over verbs GET /brick/2/delete
DELETE /brick/2
Shorter nice URI’s preferred, not required
Do not change URI’s
Use 3xx redirection if needed
Give every resource an ID http://lc/brick/1
http://lc/project/planned/223
More URI’s the better
Support for multiple data types or representations
For data use XML and/or JSON
Postfixes to define type GET /brick/2/image.jpg
GET /brick/2/image.png
Design with standards in mind – for example RSS & ATOM
Create should return URI’s not resources
Use the right HTTP methods for the right actions
You are on HTTP – use the infrastructure.
Proxy, Caching, Etag, Expires
Hyperlinks are good<project self=“http://lc/project/753”>
<bricksUsed>
<brick ref=“http://lc/brick/234” />
<brick ref=“http://lc/brick/286” />
<brick ref=“http://lc/brick/12” />
</bricksUsed>
<coloursUsed>
<colour name=“red” code=“ff0000” ref=“http://lc/brick/red”/>
</coloursUsed>
</project>
Offer paging<bricks self=“http://lc/bricks”>
<link rel=“next” ref=“http://lc/bricks?page=20” />
…
</bricks>
<bricks>
<brick ref=“http://lc/brick/1” />
<brick ref=“http://lc/brick/2” />
<brick ref=“http://lc/brick/3” />
</brick>
<bricks>
<brick ref=“http://lc/brick/1”>
<colour>red</colour>
</brick>
<brick ref=“http://lc/brick/2”>
<colour>red</colour>
</brick>
<brick ref=“http://lc/brick/3”>
<colour>red</colour>
</brick>
</brick>
Offer collections of information
Use one HTTP method – like GET for everything
Often called GET or POST Tunnelling
Pass everything in URI’s
Assume this is a replacement for SOAP or WS*
Are RESTful services secure? It’s a style, not a technology so that depends on how you
implement it.Are you open to SQL injection attacks? When you look at http://bbddb01/northwind/users[firstname=“rob%”], you
may think so but you shouldn’t be. Because: The parameter shouldn’t be SQL If it is SQL, why are you not filtering it?
Remember the old rule: Do not trust user inputURI’s are user input
How can I do authentication?
It’s built on HTTP, so everything you have for authentication in HTTP is available
PLUS
You could encode your authentication requirements into the input fields
WCF Data Services
Previously called ADO.NET Data Services & Astoria
NerdDinner.com
Twitter.com
MediaWiki
Their action’s are frowned upon by purists
Highly scalable
Designed for HTTP and stateless
Easy to consume
No complex request/response model.
No complex XML contracts
Easy to understand for you and machines
URI + Method = Intent