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
1
200
REST API Design, Part II
Given at PHP Undiscovered, SF.
Nate Abele
August 30, 2013
Tweet
Share
More Decks by Nate Abele
See All by Nate Abele
Running Kubernetes in the Browser. Yes, really. Not really. Kind of.
nateabele
1
31
Un-dux Your Front-End
nateabele
1
100
CloudFormation For Fun & Profit (But Mostly Sanity)
nateabele
0
72
Functional Reactive Systems
nateabele
1
140
ngPittsburgh - AngularUI Router Philosophy
nateabele
1
1.1k
The Future of Programming
nateabele
1
490
Past, Present, and Future: The Evolution of PHP Development
nateabele
1
560
The Future of Programming: PHP Argentina 2014
nateabele
1
120
Designing Hypermedia APIs
nateabele
4
650
Other Decks in Programming
See All in Programming
Signal-Based Data FetchingWith the New httpResource
manfredsteyer
PRO
0
130
AtCoder Heuristic First-step Vol.1 講義スライド(山登り法・焼きなまし法編)
takumi152
4
1k
自分のために作ったアプリが、グローバルに使われるまで / Indie App Development Lunch LT
pixyzehn
1
140
これだけは知っておきたいクラス設計の基礎知識 version 2
masuda220
PRO
21
4.7k
英語文法から学ぶ、クリーンな設計の秘訣
newnomad
1
280
SEAL - Dive into the sea of search engines - Symfony Live Berlin 2025
alexanderschranz
1
110
リアルタイムレイトレーシング + ニューラルレンダリング簡単紹介 / Real-Time Ray Tracing & Neural Rendering: A Quick Introduction (2025)
shocker_0x15
1
270
Compose Hot Reload is here, stop re-launching your apps! (Android Makers 2025)
zsmb
1
260
SLI/SLOの設定を進めるその前に アラート品質の改善に取り組んだ話
tanden
2
780
Do Dumb Things
mitsuhiko
0
390
複数ドメインに散らばってしまった画像…! 運用中のPHPアプリに後からCDNを導入する…!
suguruooki
0
450
小さく段階的リリースすることで深夜メンテを回避する
mkmk884
2
150
Featured
See All Featured
Java REST API Framework Comparison - PWX 2021
mraible
29
8.5k
The World Runs on Bad Software
bkeepers
PRO
67
11k
GraphQLの誤解/rethinking-graphql
sonatard
70
10k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Visualization
eitanlees
146
16k
Why Our Code Smells
bkeepers
PRO
336
57k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
12
630
Build your cross-platform service in a week with App Engine
jlugia
229
18k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
12
1.4k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.4k
Large-scale JavaScript Application Architecture
addyosmani
511
110k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
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:pass@my.api/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