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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
79
Un-dux Your Front-End
nateabele
1
160
CloudFormation For Fun & Profit (But Mostly Sanity)
nateabele
0
91
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
650
The Future of Programming: PHP Argentina 2014
nateabele
1
130
Designing Hypermedia APIs
nateabele
4
720
Other Decks in Programming
See All in Programming
1B+ /day規模のログを管理する技術
broadleaf
0
110
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
390
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
570
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
170
AI 輔助遺留系統現代化的經驗分享
jame2408
1
990
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
210
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
160
The NotImplementedError Problem in Ruby
koic
1
930
Spring Security 実践 ─ GraphQL APIで実務に役立つ 認証・認可 を学ぶ
wagyu
0
260
Claspは野良GASの夢をみるか
takter00
0
210
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
560
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
740
Featured
See All Featured
Music & Morning Musume
bryan
47
7.2k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
150
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
Git: the NoSQL Database
bkeepers
PRO
432
67k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
210
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
What's in a price? How to price your products and services
michaelherold
247
13k
HDC tutorial
michielstock
2
720
Being A Developer After 40
akosma
91
590k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
330
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
620
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
66
55k
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