Slide 1

Slide 1 text

Crafting a Great Webhooks Experience John Sheehan CEO, @Runscope Tuesday, October 7, 14

Slide 2

Slide 2 text

Tuesday, October 7, 14

Slide 3

Slide 3 text

Tuesday, October 7, 14

Slide 4

Slide 4 text

Tuesday, October 7, 14

Slide 5

Slide 5 text

Tuesday, October 7, 14

Slide 6

Slide 6 text

Tuesday, October 7, 14

Slide 7

Slide 7 text

"user defined callbacks made with HTTP POST" Tuesday, October 7, 14

Slide 8

Slide 8 text

"Webhooks are the easiest way to remotely execute code." -- Jeff Lindsay once when we were talking Tuesday, October 7, 14

Slide 9

Slide 9 text

HTTP Push Notifications Tuesday, October 7, 14

Slide 10

Slide 10 text

A Reverse API Tuesday, October 7, 14

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

Tuesday, October 7, 14

Slide 15

Slide 15 text

Implementing Webhooks Tuesday, October 7, 14

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Problem #1: Error Handling Tuesday, October 7, 14

Slide 18

Slide 18 text

> POST /callback < 400 Bad Request Tuesday, October 7, 14

Slide 19

Slide 19 text

> POST /callback < 302 Found < Location: http:// Tuesday, October 7, 14

Slide 20

Slide 20 text

> POST /callback < 200 OK < Content-Type: text/plain < Tuesday, October 7, 14

Slide 21

Slide 21 text

Error Handling Suggestions Tuesday, October 7, 14

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

Problem #2: Flooding Tuesday, October 7, 14

Slide 26

Slide 26 text

Tuesday, October 7, 14

Slide 27

Slide 27 text

Active Queues ↪ ↪ Tuesday, October 7, 14

Slide 28

Slide 28 text

Problem #3: Security Tuesday, October 7, 14

Slide 29

Slide 29 text

> POST http://localhost:3000 Tuesday, October 7, 14

Slide 30

Slide 30 text

> POST http://foo.lvh.me Tuesday, October 7, 14

Slide 31

Slide 31 text

DoS Attack Vector Tuesday, October 7, 14

Slide 32

Slide 32 text

Proving the Source Tuesday, October 7, 14

Slide 33

Slide 33 text

Validation Techniques Tuesday, October 7, 14

Slide 34

Slide 34 text

Key Sharing Tuesday, October 7, 14

Slide 35

Slide 35 text

Request Signing Tuesday, October 7, 14

Slide 36

Slide 36 text

Re-fetch > POST /callback > { id: 123 } > GET /users/123 < { id: 123 } Webhook Callback App Code Tuesday, October 7, 14

Slide 37

Slide 37 text

Security Suggestions Tuesday, October 7, 14

Slide 38

Slide 38 text

Validate your requests. Document it well! Resolve IPs before making request. Consider proxying. Consider subscription validation for high-volume cases. Tuesday, October 7, 14

Slide 39

Slide 39 text

Validate your requests. Document it well! Resolve IPs before making request. Consider proxying. Consider subscription validation for high-volume cases. Tuesday, October 7, 14

Slide 40

Slide 40 text

Validate your requests. Document it well! Resolve IPs before making request. Consider proxying. Consider subscription validation for high-volume cases. Tuesday, October 7, 14

Slide 41

Slide 41 text

Developer Experience Tuesday, October 7, 14

Slide 42

Slide 42 text

Payload Design Tuesday, October 7, 14

Slide 43

Slide 43 text

Fat vs.Thin Tuesday, October 7, 14

Slide 44

Slide 44 text

- or - { } payload= Tuesday, October 7, 14

Slide 45

Slide 45 text

- or - data = JSON.loads(request.body) name = data["name"] name = request.form.get("name") Tuesday, October 7, 14

Slide 46

Slide 46 text

payload = request.form.get("payload") data = JSON.loads(payload) name = data["name"] Tuesday, October 7, 14

Slide 47

Slide 47 text

Mirror API Resources Tuesday, October 7, 14

Slide 48

Slide 48 text

Complete Documentation! Tuesday, October 7, 14

Slide 49

Slide 49 text

Tooling Tuesday, October 7, 14

Slide 50

Slide 50 text

Accept Multiple Callback URLs Tuesday, October 7, 14

Slide 51

Slide 51 text

Hooks API Tuesday, October 7, 14

Slide 52

Slide 52 text

Debugger & Logs Tuesday, October 7, 14

Slide 53

Slide 53 text

Manual Retries Tuesday, October 7, 14

Slide 54

Slide 54 text

Generate Test Callbacks Tuesday, October 7, 14

Slide 55

Slide 55 text

Tunneling Tuesday, October 7, 14

Slide 56

Slide 56 text

Thank you! Questions? Try Runscope free: runscope.com Tuesday, October 7, 14