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
220
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
130
Sexy Time with Nick Sutterer
apotonick
1
430
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Designing for Performance
lara
604
68k
We Have a Design System, Now What?
morganepeng
50
7.2k
A Tale of Four Properties
chriscoyier
156
23k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
130
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
44
2.2k
Bash Introduction
62gerente
608
210k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
16
2.1k
GraphQLとの向き合い方2022年版
quramy
43
13k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.2k
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