Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Hypermedia For Y'All
Search
apotonick
December 27, 2011
0
250
Hypermedia For Y'All
The presentation I gave at the RubyConf Brazil 2011.
apotonick
December 27, 2011
Tweet
Share
More Decks by apotonick
See All by apotonick
Off The Tracks
apotonick
4
140
Sexy Time with Nick Sutterer
apotonick
1
470
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
57
5.9k
The Straight Up "How To Draw Better" Workshop
denniskardys
238
140k
Building a Scalable Design System with Sketch
lauravandoore
463
33k
How to Think Like a Performance Engineer
csswizardry
27
2.1k
Statistics for Hackers
jakevdp
799
220k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
640
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
Making Projects Easy
brettharned
120
6.4k
Faster Mobile Websites
deanohume
310
31k
Intergalactic Javascript Robots from Outer Space
tanoku
272
27k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.7k
A better future with KSS
kneath
239
18k
Transcript
Roar! Nick „The German“ Sutterer @apotonick Hypermedia for y'all! The
Missing Ingredient in REST
2 Roar! 43.8 minutes... REST Representations Hypermedia Roooaaar
3 Roar! REST?
4 Roar! „architectural style for distributed hypermedia systems“ Roy Fielding's
dissertation, chapter 5, line 1
5 Roar! require 'rest' class Application include Restful end
6 Roar! GET http://nick/state {„status“ : „sober“}
Roar! Resource Unique URL http://beer/rocky Uniform Interface GET POST PUT
... Represen- tation
Roar! „REST“ monolithic app pretty URLs GET renders models (JSON/HTML)
POST to create and update models
Roar! Mono- lithic Systems
Roar! componentized app ...still pretty URLs real REST services with
GET, PUT, POST, DELETE no HTML! embedded hypermedia REST
Roar! Split it!
Roar! BURP! Order!
Roar! BURP! Beer shop system Using RESTful backend services and
a separate Presentation layer !
Roar! A typical REST session!
Roar! GET/PUT/ http://... ------------------- <document> ------------------- <document>
Roar! GET http://beers/1 name: Rocky alc : 6.0
Roar! POST http://beers/ ------------------- name: Beck's alc : 5.1 Created!
It's at http://beers/becks
18 Roar! GET: show POST: create PUT: update ... REST
is
19 Roar! CRUD is not REST!
Roar! A hypermedia- driven REST session!
Roar! BURP! Order!
Roar! BURP! REST Service Client
23 Roar! BURP!
24 Roar! BURP!
Roar! GET http://orders/1 id: 1 created_at: August 30 to proceed:
http://orders/1/pay to update: http://orders/1
Roar! to proceed: http://orders/1/pay to update: http://orders/1 „ HATEOAS“ WTF?
Roar! „HATEOAS“ - embedd actions that make sense in current
application state
Roar! {order: { id : 1 created_at: August 31 links
: [ {rel : proceed href: http://orders/1/pay} {rel : self href: http://orders/1} ] } Hypermedia & JSON
Roar! rel : proceed href: http://orders/1/pay
30 Roar! <link rel =„proceed“ href =„http://orders/1/pay“ />
Roar! rel – link semantic, „meaning“ href – resource URL
Roar! Creating a new order
Roar! POST http://orders ------------------------ client_id: 42 id : 1 client_id:
42 beers : [] links : [ {rel : self href: http://orders/1} {rel : beers href: http://orders/1/be ]
Roar! Single entry point – the one and only URL
we know POST http://orders ------------------------ client_id: 42
Roar! id : 1 client_id: 42 beers : [] links
: [ {rel: self href: http://orders/1} {rel: beers href: http://orders/1/beers} ] self link – pointing to current resource
Roar! id : 1 client_id: 42 beers : [] links
: [ {rel: self href: http://orders/1} {rel: beers href: http://orders/1/beers} ] beers link – items placed in order
Roar! GET the new order
Roar! GET http://orders/1 id : 1 client_id: 42 beers :
[] links : [ {rel : self href: http://orders/1} {rel : beers href: http://orders/1/be ]
Roar! Follow the beers link
Roar! GET http://orders/1/beers beers: [] links: [ {rel : self
href: http://orders/1/be {rel : order href: http://orders/1}
Roar! Add beer to order
Roar! POST http://orders/1/beers ------------------------ {name: Anchor Steam} Created! It's at
http://orders/1/beers/anchors team Created! It's at http://orders/1/beers/anchors team
Roar! Reloading the order
Roar! GET http://orders/1 id : 1 client_id: 42 beers: [
{name: Anchor Steam links: [ {rel : self href: http://orders/1/ ]} ],
Roar! id : 1 client_id: 42 beers: [ {name: Anchor
Steam links: [ {rel : self href: http://orders/1/beers/anchorsteam} ]} ], links: [ {rel: self href: http://orders/1} {rel: beers href: http://orders/1/beers} ] +
Roar! id : 1 client_id: 42 beers: [ {name: Anchor
Steam links: [ {rel : self href: http://orders/1/beers/anchorsteam} ]} ], links: [ {rel: self href: http://orders/1} {rel: beers href: http://orders/1/beers} ] +
Roar! +
Roar! Removing beer from order
Roar! DELETE http://orders/1/beers/anchorsteam +
Roar! Reloading the order
Roar! GET http://orders/1 id : 1 client_id: 42 beers :
[] links : [ {rel : self href: http://orders/1} {rel : beers href: http://orders/1/be ]
Roar! GET http://orders/1 id : 1 client_id: 42 beers :
[] links : [ {rel : self href: http://orders/1} {rel : beers href: http://orders/1/be ]
53 Roar! http://orders/ POST GET GET + DELETE ? GET
POST
54 Roar! What we didn't do... PUT http://orders/1 DELETE http://orders/1/items
...
55 Roar! Code!
Roar! Roar!
gem 'roar'
58 Roar! class Beer include Roar::Representer::JSON property :name property :id
link :self do beer_url(id) end Plain properties Hypermedia support yo
59 Roar! Beer.new(:id => 1, :name => "NickBrew").to_json from Roar
{"beer":{ "id" : 1, "name" : "NickBrew", "links": [{"rel":"self","href":"http://beers/1"}]}}
60 Roar! brew = Beer.from_json '{"beer":{ "id" : 1, "name"
: "NickBrew"}}' from Roar brew.name #=> „NickBrew“
61 Roar! class Beer include Roar::Representer::XML ... jaja brew.to_xml <beer>
<id>1</id> <name>NickBrew</name> <link rel="self" href="http://beers/1"/> </beer>
62 Roar! class Order include Roar::Representer::JSON collection Beer
63 Roar! class Collection include Roar::Representer::JSON link :next do page_url(page)
end end class Beers < Collection collection Beer
64 Roar! brew.new(:name => „SKOL“) brew.new(:name => „SKOL“) brew.extend Feature::HTTPVerbs
brew.new(:name => „SKOL“) brew.extend Feature::HTTPVerbs brew.post!(„http://beers“) brew.new(:name => „SKOL“) brew.extend Feature::HTTPVerbs brew.post!(„http://beers“) puts „I'm at“ + brew.links[:self] #=> „http://beers/99“
65 Roar!
66 Roar! „REST APIs must be hypertext-driven“: http://roy.gbiv.com/untangled/2008/rest-apis-must-be- hypertext-driven REST
in Practice – O'REILLY RESTful Web Services Cookbook – O'REILLY
67 Roar! Are you local?
Roar! Thirsty? http://github.com/apotonick/roar @apotonick