Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Crafting a Great Webhooks Experience
John Sheehan
November 20, 2015
Technology
2
420
Crafting a Great Webhooks Experience
Presented at API Strategy and Practice 2015 #apistrat
John Sheehan
November 20, 2015
Tweet
Share
More Decks by John Sheehan
See All by John Sheehan
johnsheehan
0
110
johnsheehan
2
260
johnsheehan
2
300
johnsheehan
0
130
johnsheehan
2
350
johnsheehan
2
1.6k
johnsheehan
0
53
johnsheehan
5
790
johnsheehan
1
150
Other Decks in Technology
See All in Technology
line_developers
PRO
0
1.8k
viva_tweet_x
4
2.5k
nkjzm
1
810
yasuakiomokawa
0
310
110y
3
690
tdys13
4
3.4k
layerx
1
750
kurochan
0
550
line_developers
PRO
3
480
noir_neo
0
120
pinboro
0
2k
zaki134rp
1
180
Featured
See All Featured
aarron
258
36k
marcelosomers
220
15k
sachag
446
36k
bryan
100
11k
paulrobertlloyd
71
3.6k
denniskardys
220
120k
ddemaree
274
31k
addyosmani
1348
190k
morganepeng
92
13k
danielanewman
200
19k
lara
172
9.5k
caitiem20
308
17k
Transcript
Crafting a Great Webhooks Experience John Sheehan CEO, @Runscope
None
None
None
None
None
"user defined callbacks made with HTTP POST"
"Webhooks are the easiest way to remotely execute code." --
Jeff Lindsay once when we were talking
HTTP Push Notifications
A Reverse API
Provider makes request to URL when an event happens. Consumer
sets up a server to listen for callbacks. Consumer registers callback URL with provider.
Provider makes request to URL when an event happens. Consumer
sets up a server to listen for callbacks. Consumer registers callback URL with provider.
Provider makes request to URL when an event happens. Consumer
sets up a server to listen for callbacks. Consumer registers callback URL with provider.
None
Implementing Webhooks
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)
Problem #1: Error Handling
> POST /callback < 400 Bad Request
> POST /callback < 302 Found < Location: http://
> POST /callback < 200 OK < Content-Type: text/plain <
<Response></Response>
Error Handling Suggestions
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.
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.
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.
Problem #2: Flooding
None
Active Queues ↪ ↪
Problem #3: Security
> POST http://localhost:3000
> POST http://foo.lvh.me
DoS Attack Vector
Proving the Source
Validation Techniques
Key Sharing
Request Signing
Re-fetch > POST /callback > { id: 123 } >
GET /users/123 < { id: 123 } Webhook Callback App Code
Security Suggestions
Validate your requests. Document it well! Resolve IPs before making
request. Consider proxying. Consider subscription validation for high-volume cases.
Validate your requests. Document it well! Resolve IPs before making
request. Consider proxying. Consider subscription validation for high-volume cases.
Validate your requests. Document it well! Resolve IPs before making
request. Consider proxying. Consider subscription validation for high-volume cases.
Developer Experience
Payload Design
Fat vs.Thin
Mirror API Resources
Complete Documentation!
Tooling
Accept Multiple Callback URLs
Hooks API
Debugger & Logs
Manual Retries
Generate Test Callbacks
Tunneling Recommended: ngrok.com
Thank you! Questions? john@runscope.com Try Runscope free: runscope.com