- REpresentational State Transfer
- Introduced by Roy Fielding in 2000
- Lets focus on APIs.
- Lets talk about the Richardson Maturity Model
- You're using HTTP as an RPC (Remote procedure call)
- It's a start
What meetings exist?
POST /meetingsList
HTTP/1.1 200 OK
<other headers>
[
{
'title' : 'Meeting - Backbone.js',
'date' : '02-07-2012',
'organization' : 'WIT',
'id' : 'meeting00'
}
]
Cool, we need a new one
POST /createMeetingPlease
{
'title' : 'Weekly Meeting - REST',
'date' : '02-14-2012',
'organization' : 'WIT'
}
HTTP/1.1 200 OK
<other headers>
{
'title' : 'Meeting - REST',
'date' : '02-14-2012',
'organization' : 'WIT',
'id' : 'meeting01'
}
And let me check in
POST /checkInToMeeting
{
'name' : 'Mike Skalnik',
'meetingId' : 'meeting01'
}
HTTP/1.1 200 OK
<other headers>
{
'name' : 'Mike Skalnik',
'meetingId' : 'meeting01',
'id' : 'checkin01'
}
- RESTful URIs.
- Represent objects in your URIs
What meetings exist?
POST /meetings/list
HTTP/1.1 200 OK
<other headers>
[{
'title' : 'Meeting - Backbone.js',
'date' : '02-07-2012',
'organization' : 'WIT',
'id' : 0
}]
Cool, we need a new one
POST /orgs/WIT/meetings/create
{
'title' : 'Weekly Meeting - REST',
'date' : '02-14-2012'
}
HTTP/1.1 200 OK
<other headers>
{
'title' : 'Meeting - REST',
'date' : '02-14-2012',
'organization' : 'WIT',
id : 1
}
And lets check in
POST /meetings/meeting01/checkins/create
{
'name' : 'Mike Skalnik'
}
HTTP/1.1 200 OK
<other headers>
{
'name' : 'Mike Skalnik',
'id' : 1
}
- Use HTTP verbs on those resources
- GET/POST/PUT/DELETE
What meetings exist?
GET /meetings
HTTP/1.1 200 OK
<other headers>
{
'title' : 'Meeting - Backbone.js',
'date' : '02-07-2012',
'organization' : 'WIT',
'id' : 0
}
Cool, we need a new one
POST /orgs/WIT/meetings
{
'title' : 'Weekly Meeting - RSET',
'date' : '02-14-2012'
}
HTTP/1.1 201 Created
<other headers>
{
'title' : 'Meeting - RSET',
'date' : '02-14-2012',
'organization' : 'WIT',
'id' : 1
}
Oh no, I typo'd the title. Lets update it
PUT /meetings/1
{
'title' : 'Meeting - REST'
}
HTTP/1.1 200 OK
<other headers>
{
'title' : 'Meeting - REST',
'date' : '02-14-2012',
'organization' : 'WIT',
'id' : 1
}
Eh, lets just delete
DELETE /meetings/1
HTTP/1.1 200 OK
<other headers>
I want JSON!
GET /meetings
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
[
{
'title' : 'Weekly Meeting - Backbone.js'
'id' : 0
}
]
Actually, XML!
GET /meetings
Accept: application/xml
HTTP/1.1 200 OK
Content-Type: application/xml
<meetings>
<meeting id="0">
<title>Weekly Meeting - Backbone.js</title>
</meeting>
</meetings>
- This is pretty damn cool. You can use custom MIME types to version our APIs
- People normally start shoving versions in their URL, not so RESTful
API V1 in JSON:
GET /meetings
Accept: application/vnc.ccorgs-v1+json
V2 in JSON:
GET /meetings
Accept: application/vnc.ccorgs-v2+json
V1 in XML:
GET /meetings
Accept: application/vnc.ccorgs-v1+xml
- My interest recently
- APIs serve links, like the links you click on
- REST is all about state. Your web app is a state machine!
- Hypertext being XML, but you can do this with the HTTP Link header for non-hypertext.
Tell me about the first meeting
GET /meetings/0
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Link: </meetings>; rel="up", </meetings/0/checkins>; rel="checkins", \
</meetings?page=2>; rel="next", </meetings?page=100>; rel="last"
<other headers>
[
{
'title' : 'Meeting - Backbone.js',
'date' : '02-07-2012',
'organization' : 'WIT',
'id' : 0
}
]
Cool, lets make a new meeting
POST /meetings
{
'title' : 'Weekly Meeting - REST',
'date' : '02-14-2012'
}
HTTP/1.1 201 Created
Content-Type: application/json
Location: /meetings/1
Link: </meetings/1/checkins>; rel="checkins"
<other headers>
{
'title' : 'Meeting - RSET',
'date' : '02-14-2012',
'organization' : 'WIT',
'id' : 1
}
Lets check if anyone has checked in yet. I'll just follow that link.
GET /meetings/1/checkins
HTTP/1.1 200 OK
Link: </meetings/1>; rel="up"
<other headers>
[
{
'name' : 'Mike Skalnik',
'timestamp' : '1329262247'
},
{
'name' : 'Ankit Shankar'
'timestamp' : '1329262534'
}
]
http://blog.kevburnsjr.com/self-descriptive-hypermedia-in-riak is cool. I can't wait for http://getsomere.st/
Once you're messing with HATEOAS, you shouldn't be messing with URLs anymore. You should just send your HTTP requests to the links sent in the server response (either in the body if its hypertext, or in the
Link
header). However, we still want to be able to support multiple content types, so we need to send it via theAccept
header. Does that make sense?