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
REST API Design, Part II
Search
Nate Abele
August 30, 2013
Programming
230
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
REST API Design, Part II
Given at PHP Undiscovered, SF.
Nate Abele
August 30, 2013
More Decks by Nate Abele
See All by Nate Abele
Running Kubernetes in the Browser. Yes, really. Not really. Kind of.
nateabele
1
84
Un-dux Your Front-End
nateabele
1
160
CloudFormation For Fun & Profit (But Mostly Sanity)
nateabele
0
96
Functional Reactive Systems
nateabele
1
190
ngPittsburgh - AngularUI Router Philosophy
nateabele
1
1.2k
The Future of Programming
nateabele
1
600
Past, Present, and Future: The Evolution of PHP Development
nateabele
1
660
The Future of Programming: PHP Argentina 2014
nateabele
1
130
Designing Hypermedia APIs
nateabele
4
720
Other Decks in Programming
See All in Programming
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
320
AI時代の仕事技芸論〜ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ(スクフェス仙台 2026バージョン)
kuranuki
0
660
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
1.1k
act2-costs.pdf
sumedhbala
0
120
AI がコードを書く時代における新卒エンジニアの仕事風景 (2026) / New Graduate Engineers in the Era of AI Coding (2026)
sushichan044
0
220
PHPだって関数型したい 〜できること、できないこと〜 / fp-in-php
jsoizo
0
220
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
170
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
400
5分で問診!Composer セキュリティ健康診断
codmoninc
0
360
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
190
地域 SRE コミュニティ最前線 - ホンマでっかSRE勉強会
tk3fftk
0
250
えっ!!コードを読まずに開発を!?
hananouchi
0
220
Featured
See All Featured
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
310
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.6k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
400
Odyssey Design
rkendrick25
PRO
2
730
HDC tutorial
michielstock
2
750
How STYLIGHT went responsive
nonsquared
100
6.2k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
270
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.6k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Balancing Empowerment & Direction
lara
6
1.2k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Transcript
The Dream of the 90’s is Withering on the Vine
(in Portland)
How to Future-Proof & Increase The Level of Sanity in
the Design of Your APIs, by Respecting the Best Practices of HTTP Or...
This is Roy
Principles • Client-Server • Stateless • Cacheable • Uniform Interface
• Opaque Layering • Code-on-Demand
Objectives •Auth •Querying •Relationships •Pagination •Formats •Caching •Logging •API Versioning
Auth •Simple! •Basic vs. Digest (over SSL, obviously) •Upshot of
Basic: http://user:
[email protected]
/objects •Cookies? •Custom Tokens?
Querying •There are approaches to making this discoverable •They are
ridiculously ivory-tower •Better: ?q=<whatever>
Relationships •Goal: Introspect API domain model and transform object relationships
to URLs
Relationships GET /tasks HTTP/1.1 [{ title: "Finish client demo", completed:
false, _links: { self: { href: "http://my.app/tasks/1138" }, owner: { href: "http://my.app/users/nate" }, subtasks: { href: "http://my.app/tasks/1138/subtasks" } } }]
Pagination GET /tasks?page=5&order=due ?
Pagination HTTP Range! GET /videos/rickroll.mp4 Range: bytes=100-99999
Pagination HEAD /tasks HTTP/1.1 ... HTTP 200 OK Accept-Ranges: tasks
Pagination HEAD /posts HTTP/1.1 ... HTTP 200 OK Accept-Ranges: posts
Pagination GET /posts HTTP/1.1 Range: posts=1-20
Caching (Strategies) • Generated cache keys (ETag, If-None-Match) • For
writes: If-Match • Time-based (Last-Modified / If-Modified-Since)
Logging Custom Response Headers!
Logging X-Query-Log: SELECT * From users WHERE name = "nate"
X-Query-Log: SELECT * From tasks WHERE user_id = 13
Logging X-Query-Log: users.find({ name: "nate" })
DEMO