crud is not rest! hypermedia for y'all!
TRANSCRIPT
R o a r!
Nick „The German“ Sutterer
OMG, he's on the twitter, finally!@apotonick
Hypermediafor y'all!
2
R o a r!
45 minutes...
REST
Hypermedia
ROAR
3
R o a r!
„architectural style for distributed hypermedia systems“
Roy Fielding's dissertation, chapter 5, line 1
4
R o a r!
require 'rest'
class Application include Restfulend
5
R o a r!
GET http://nick/state
{„status“ : „tired“,„status-fr“: „fatigue“}
R o a r!
Resource Unique URL
http://wines/red/1
UniformInterface GET
POSTPUT...
Represen-tation
R o a r!
GET http://wines/red/1
{„color“: „red“, „alc“: 12.8, …}
R o a r!
POSThttp://wines/
{„color“: „red“, „alc“: 12.8 }
http://wines/red/1
{„id“: 1, „color“: „red“, „alc“: 12.8,}
R o a r!
GET http://wines/red/1Content-Type: app/wine+json
<body>
R o a r!
JSON
Representations==
Documents
11
R o a r!
GET: showPOST: createPUT: update...
REST is
CRUD is notREST!
R o a r!
<wine> <id>1</id> <color>red</color>
<link rel=“buy“ href=“http://wine/buy/1“ />
14
R o a r!
Order
Article
User
Variant
Size
RoleClient
Address Shipping
Authenti-cation
Price
15
R o a r!
Order
Article
User
Variant
Size
RoleClientAddress Shipping Authenti-cation
Price
16
R o a r!
„Tab“ = Ordered drinks per Table
RESTaurant
17
R o a r!
RESTaurant.tabs.add(table_3)
POST http://tabs
18
R o a r!
{„tab“: { „table“: 3, „drinks“: [], ...}}
?
!
POST http://tabs{„tab“: {„table“: 3}}
REST client!
19
R o a r!
{„tab“: { „id“: 42 „table“: 3, „drinks“: [], „links“: [ {„rel“ => „self“, „href“ => „http://tabs/42“},
{„rel“ => „order“, „href“ => „http://tabs/42/order/{name}“}
{„rel“ => „pay“, „href“ => „http://tabs/42/pay“} ]}}
Hyper
med
ia!
20
R o a r!
{„rel“ => „pay“, „href“ => „http://tabs/42/pay“}
21
R o a r!
<tab> <id>42</id> <table>3</table> <drinks />
<link rel=„self“ href=„http://tabs/42“ /> <link rel =„order“ href=„http://tabs/42/order/{name}“ />
<link rel=„pay“ href=„http://tabs/42/pay“ /></tab>
22
R o a r!
{„tab“: { „id“: 42 „table“: 3, „drinks“: [], „links“: [ {„rel“ => „self“, „href“ => „http://tabs/42“},
{„rel“ => „order“, „href“ => „http://tabs/42/order/{name}“}
{„rel“ => „pay“, „href“ => „http://tabs/42/pay“} ]}}
23
R o a r!
RESTaurant.tab(42).order(11)
1. look for rel=“order“2. extract href3. expand URL template4. POST
24
R o a r!
{„tab“: { „id“: 42 „table“: 3, „drinks“: [], „links“: [ {„rel“ => „self“, „href“ => „http://tabs/42“},
{„rel“ => „order“, „href“ => „http://tabs/42/order/{name}“}
{„rel“ => „pay“, „href“ => „http://tabs/42/pay“} ]}}
25
R o a r!
http://tabs/42/order/bordeaux
26
R o a r!
?
!
POST http://tabs/42/order/bordeaux
{„tab“: { „id“: 42 „table“: 3, „drinks“: [bordeaux],
27
R o a r!
http://tabs/42/order/bordeaux
NO URL computationNO guessingJust following links
28
R o a r!
Code!
29
R o a r!
{„tab“: { „table“: 3, „drinks“: [11], „links“: [ {„rel“: „self“,}}
?
!
GET http://tabs/42
30
R o a r!
class TabRepresenter < Roar::Representer::JSON
property :id, :table collection :drinks
link :self do tab_url(represented) end link :order do order_url(represented) end ...
31
R o a r!
TabRepresenter. from_model(@tab). serialize
# => {„tab“: { „id“: 42 „table“: 3, „drinks“: [11], „links“: [ {„rel“: „self“, „href“: „http://tabs/42“}...
32
R o a r!
{„tab“: { „table“: 3, „drinks“: [11], „links“: [...
?
!
POST http://tabs{„tab“: {„table“: 3, „drinks“: 11}}
33
R o a r!
TabRepresenter. deserialize(json_body). to_nested_attributes
# => {:table => 3, :drink_ids => [11]}
TableOrder.create(attrs)
34
R o a r!
?
!
POST http://tabs/42/order/11
35
R o a r!
tab = TabRepresenter. from(:table => 3). post(„http://tabs“)
36
R o a r!
tab.links[:order]. # => „http://tabs/42/order/{id}
expand(:id => 11).
post!
37
R o a r!
@apotonick
http://github.com/apotonick/roar