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
Crafting a Great Webhooks Experience
Search
John Sheehan
August 21, 2014
Technology
0
150
Crafting a Great Webhooks Experience
Presented at API Craft SF on 8/21/14
John Sheehan
August 21, 2014
Tweet
Share
More Decks by John Sheehan
See All by John Sheehan
My Favorite API Tools (Other than Runscope)
johnsheehan
0
140
Crafting a Great Webhooks Experience
johnsheehan
2
480
Glue 2015: Microservices - More than just a buzzword.
johnsheehan
2
550
Scale-Oriented Architecture with Microservices
johnsheehan
2
330
The rise of distributed applications.
johnsheehan
2
400
Zen and the Art of API Maintenance
johnsheehan
2
2.3k
Building API integrations you can live with.
johnsheehan
0
98
Free API debugging and testing tools you should know about.
johnsheehan
5
820
Modern Tools for Modern Applications
johnsheehan
1
170
Other Decks in Technology
See All in Technology
[NIKKEI Tech Talk] KDDI/KAG Scrum & Community for Engineering Training
curanosuke
2
220
Datadog Cloud SIEMを使ってAWS環境の脅威を可視化した話/lifeistech-datadog-cloud-siem
gidajun
0
480
CTOから見た事業開発とプロダクト開発 / My Perspective on Business and Product Development as CTO
keisuke69
4
960
AIエージェントを現場に導入する目線とは
masahiro_nishimi
1
1.5k
What is DRE? - Road to SRE NEXT@広島
chanyou0311
3
630
Classmethod流のPlatform Engineering / classmethod-platform-engineering-devio2024
tomoki10
0
480
AWSで”最小権限の原則”を実現するための考え方 /20240722-ssmjp-aws-least-privilege
opelab
10
4.4k
初中級者用如何使用backlog -VALE TUDOEDITION-
in0u
0
140
[I/O Extended Android 2024] What`s new in Android 2024
kyeongwan
0
220
楽しくGoを学び合う、LayerXの勉強会文化 / LayerX's study culture of having fun and learning Go together
ar_tama
2
350
ここがすごいよ! AWS Systems Manager!
saichan11
0
1.8k
20240725 LLMによるDXのビジョンと、今何からやるべきか @Azure OpenAI Service Dev Day
nrryuya
3
1.2k
Featured
See All Featured
Thoughts on Productivity
jonyablonski
64
4.1k
How to name files
jennybc
67
96k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
18
1.2k
Fireside Chat
paigeccino
25
2.8k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
360
22k
The Illustrated Children's Guide to Kubernetes
chrisshort
39
47k
How GitHub Uses GitHub to Build GitHub
holman
471
290k
BBQ
matthewcrist
82
9k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
224
21k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
26
1.8k
WebSockets: Embracing the real-time Web
robhawkes
59
7.2k
Imperfection Machines: The Place of Print at Facebook
scottboms
262
13k
Transcript
Crafting a Great Webhooks Experience John Sheehan CEO, @Runscope Tuesday,
October 7, 14
Tuesday, October 7, 14
Tuesday, October 7, 14
Tuesday, October 7, 14
Tuesday, October 7, 14
Tuesday, October 7, 14
"user defined callbacks made with HTTP POST" Tuesday, October 7,
14
"Webhooks are the easiest way to remotely execute code." --
Jeff Lindsay once when we were talking Tuesday, October 7, 14
HTTP Push Notifications Tuesday, October 7, 14
A Reverse API Tuesday, October 7, 14
Provider makes request to URL when an event happens. Consumer
sets up a server to listen for callbacks. Consumer registers callback URL with provider. Tuesday, October 7, 14
Provider makes request to URL when an event happens. Consumer
sets up a server to listen for callbacks. Consumer registers callback URL with provider. Tuesday, October 7, 14
Provider makes request to URL when an event happens. Consumer
sets up a server to listen for callbacks. Consumer registers callback URL with provider. Tuesday, October 7, 14
Tuesday, October 7, 14
Implementing Webhooks Tuesday, October 7, 14
url = get_callback_url() data = get_webhook_payload_json() try: resp = requests.post(url,
data=data) if not resp.ok: _logger.error(resp.content) except Exception as e: _logger.error(e) Tuesday, October 7, 14
Problem #1: Error Handling Tuesday, October 7, 14
> POST /callback < 400 Bad Request Tuesday, October 7,
14
> POST /callback < 302 Found < Location: http:// Tuesday,
October 7, 14
> POST /callback < 200 OK < Content-Type: text/plain <
<Response></Response> Tuesday, October 7, 14
Error Handling Suggestions Tuesday, October 7, 14
Be lenient in what you accept back if you can
reasonably guess. Retry failed callbacks with exponential back off. Decide if redirects are to be followed or not. Tuesday, October 7, 14
Be lenient in what you accept back if you can
reasonably guess. Retry failed callbacks with exponential back off. Decide if redirects are to be followed or not. Tuesday, October 7, 14
Be lenient in what you accept back if you can
reasonably guess. Retry failed callbacks with exponential back off. Decide if redirects are to be followed or not. Tuesday, October 7, 14
Problem #2: Flooding Tuesday, October 7, 14
Tuesday, October 7, 14
Active Queues ↪ ↪ Tuesday, October 7, 14
Problem #3: Security Tuesday, October 7, 14
> POST http://localhost:3000 Tuesday, October 7, 14
> POST http://foo.lvh.me Tuesday, October 7, 14
DoS Attack Vector Tuesday, October 7, 14
Proving the Source Tuesday, October 7, 14
Validation Techniques Tuesday, October 7, 14
Key Sharing Tuesday, October 7, 14
Request Signing Tuesday, October 7, 14
Re-fetch > POST /callback > { id: 123 } >
GET /users/123 < { id: 123 } Webhook Callback App Code Tuesday, October 7, 14
Security Suggestions Tuesday, October 7, 14
Validate your requests. Document it well! Resolve IPs before making
request. Consider proxying. Consider subscription validation for high-volume cases. Tuesday, October 7, 14
Validate your requests. Document it well! Resolve IPs before making
request. Consider proxying. Consider subscription validation for high-volume cases. Tuesday, October 7, 14
Validate your requests. Document it well! Resolve IPs before making
request. Consider proxying. Consider subscription validation for high-volume cases. Tuesday, October 7, 14
Developer Experience Tuesday, October 7, 14
Payload Design Tuesday, October 7, 14
Fat vs.Thin Tuesday, October 7, 14
- or - { } payload= Tuesday, October 7, 14
- or - data = JSON.loads(request.body) name = data["name"] name
= request.form.get("name") Tuesday, October 7, 14
payload = request.form.get("payload") data = JSON.loads(payload) name = data["name"] Tuesday,
October 7, 14
Mirror API Resources Tuesday, October 7, 14
Complete Documentation! Tuesday, October 7, 14
Tooling Tuesday, October 7, 14
Accept Multiple Callback URLs Tuesday, October 7, 14
Hooks API Tuesday, October 7, 14
Debugger & Logs Tuesday, October 7, 14
Manual Retries Tuesday, October 7, 14
Generate Test Callbacks Tuesday, October 7, 14
Tunneling Tuesday, October 7, 14
Thank you! Questions? Try Runscope free: runscope.com Tuesday, October 7,
14