Slide 1

Slide 1 text

by your friend: ! Ryan Weaver @weaverryan REST API’s What I Wish Someone Had Told Me

Slide 2

Slide 2 text

KnpUniversity.com github.com/weaverryan Who is this Hipster? > Lead for the Symfony documentation
 > KnpLabs US - Symfony Consulting, training, Kumbaya ! > Writer for KnpUniversity.com Tutorials > Husband of the much more talented @leannapelham

Slide 3

Slide 3 text

Chapter 0 ! I thought this would be easy @weaverryan “

Slide 4

Slide 4 text

@weaverryan

Slide 5

Slide 5 text

@weaverryan GET /api/programmers/5 HTTP 1.1! Host: CodeBattles.io! Accept: application/json,text/html HTTP/1.1 200 OK! Content-Type: application/json! ! {! "id": 5,! "nickname": "Namespacinator"! }

Slide 6

Slide 6 text

@weaverryan Documentation Resources Hypermedia HATEOAS Testing Representations Resource State $MJFOU4UBUF Status Codes Links Embedded Resources Content-Negotation Location Header Idempotency PUT, POST, PATCH Pagination Filtering

Slide 7

Slide 7 text

Chapter 1 ! Don’t be a hero @weaverryan !

Slide 8

Slide 8 text

TIP! Research Services @weaverryan

Slide 9

Slide 9 text

> design your API ! > play with it ! > implement ! > use your design as a test @weaverryan

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Chapter 2 ! Documentation/design beats out implementation @weaverryan

Slide 12

Slide 12 text

If you build it with no (or incorrect) docs… ! people can’t use it womp womp @weaverryan

Slide 13

Slide 13 text

TIP! Use a tool like Apiary or Behat @weaverryan

Slide 14

Slide 14 text

@weaverryan

Slide 15

Slide 15 text

@weaverryan

Slide 16

Slide 16 text

@weaverryan

Slide 17

Slide 17 text

knpuniversity.com/screencast/rest WebApiContext https://github.com/Behat/CommonContexts

Slide 18

Slide 18 text

Chapter 3 ! Avoid the Hype (make it work) @weaverryan

Slide 19

Slide 19 text

Let’s create a Programmer

Slide 20

Slide 20 text

POST /api/programmers HTTP/1.1! Host: CodeBattles.io! Content-type: application/json! Accept: application/json,text/html! ! {! "nickname": "ObjectOrienter",! "avatarNumber" : "2",! "tagLine": "Testing!"! } @weaverryan

Slide 21

Slide 21 text

POST /api/programmers HTTP/1.1! Host: CodeBattles.io! Content-type: application/x-www-form-urlencoded! Accept: application/json,text/html! ! nickname=ObjectOrienter&avatarN umber=2&tagLine=Testing @weaverryan

Slide 22

Slide 22 text

HTTP/1.1 201 Created! Content-type: application/json! Location: /api/programmers/2! ! {! "id": 2,! "nickname": "ObjectOrienter",! "avatarNumber" : "2",! "tagLine": "Testing!"! } @weaverryan

Slide 23

Slide 23 text

REST ! Representational State Transfer ! WTH? @weaverryan

Slide 24

Slide 24 text

TIP! Resource (URI) ! vs. ! Representation (HTML, json) … don’t over-think it @weaverryan

Slide 25

Slide 25 text

@weaverryan resource representation (a drawing)

Slide 26

Slide 26 text

@weaverryan resource representation (JSON) {! "programmers": [! { "name" : "Alice"},! { "name" : "Leanna" }! ]! }

Slide 27

Slide 27 text

TIP! Resource State* *state means “data” @weaverryan

Slide 28

Slide 28 text

REST == 1) A system where a client can change the data of 
 a resource ! ! 2) The server can respond with the data of a resource @weaverryan

Slide 29

Slide 29 text

TIP! Client State: ! It’s just the “page” your API client is on @weaverryan

Slide 30

Slide 30 text

Client: ! impacts resource state/ data by sending a representation of the desired state/data @weaverryan

Slide 31

Slide 31 text

Server: ! impacts client state by sending links that suggest what to do next (like an HTML page) @weaverryan

Slide 32

Slide 32 text

TIP! Hypermedia: ! it’s just JSON/XML with links … and sends back a special content-type header to tell the user about your format @weaverryan

Slide 33

Slide 33 text

HAL+JSON content-type: application/hal+json http://phlyrestfully.readthedocs.org/en/latest/halprimer.html

Slide 34

Slide 34 text

PNG (not hypermedia) content-type: image/png

Slide 35

Slide 35 text

My Invention content-type: application/vnd.dapper+json {! "dapper_avatar": "http://i.vimeocdn.co "other_photos": [! "https://avatars1.githubusercontent.c ],! "homepage": "https://mwop.net/"! }!

Slide 36

Slide 36 text

TIP! HATEOAS Hypermedia as the Engine of Application State Don’t believe the… @weaverryan

Slide 37

Slide 37 text

add links to be more helpful to your client @weaverryan

Slide 38

Slide 38 text

but don’t expect your API client to become self-aware and learn your API entirely by links… yet @weaverryan

Slide 39

Slide 39 text

TIP! Request Representation != Response Representation @weaverryan

Slide 40

Slide 40 text

New Programer Request {! "nickname": "ObjectOrienter",! "avatarNumber" : "2",! "tagLine": "Testing!"! } @weaverryan

Slide 41

Slide 41 text

New Programer Response @weaverryan {! "_links": {! "self": {! "href": "http://example.org/ }! },! "id": "2",! "nickname": "ObjectOrienter",! "tagLine": "Testing!"! }!

Slide 42

Slide 42 text

Chapter 4 ! It doesn’t have to be good It has to be consistent @weaverryan

Slide 43

Slide 43 text

TIP! Use objects and a serializer JMSSerializer @weaverryan http://jmsyst.com/libs/serializer

Slide 44

Slide 44 text

@weaverryan

Slide 45

Slide 45 text

@weaverryan

Slide 46

Slide 46 text

@weaverryan

Slide 47

Slide 47 text

Serialization includes everything: ! > Links > Embedded Resources > Pagination** > Filters** > Hypermedia Formatting ** BTW, use query parameters for pagination and filtering

Slide 48

Slide 48 text

HATEOAS (library)

Slide 49

Slide 49 text

@weaverryan

Slide 50

Slide 50 text

TIP! application/problem+json ! Consistency with errors @weaverryan

Slide 51

Slide 51 text

@weaverryan HTTP/1.1 400 Bad Request Content-Type: application/problem+json ! { "errors": {"nickname":"Enter a clever nickname"}, "status":400, "type": " http://example.com /docs/errors#validation_error”, "title":"There was a validation error” }

Slide 52

Slide 52 text

@weaverryan

Slide 53

Slide 53 text

Return this format in *all* error situations And add exception handlers to guarantee this

Slide 54

Slide 54 text

@weaverryan Silex! Oh crap, something went wild!

Slide 55

Slide 55 text

@weaverryan Let’s keep our head’s straight. Create that nice ApiProblem object.

Slide 56

Slide 56 text

@weaverryan type should be a URL. It’s about making it obvious what how to find out more

Slide 57

Slide 57 text

@weaverryan all gravy now!

Slide 58

Slide 58 text

TIP! Be consistent, but simple, with status codes 200: most response 201: after creating a resource 204: a 200, but blank response (e.g. delete resource) 400: validation errors or bad data format 401/403: Unauthorized/Access Denied 500: things are not good 202: If the resource will be created later 422: Could be used for validation errors

Slide 59

Slide 59 text

TIP! Don’t get obsessed with multiple formats and content-type negotiation @weaverryan

Slide 60

Slide 60 text

TIP! Don’t get obsessed with *accepting* multiple input formats ! “we support sending json, XML or www- form-urlencoded data!” @weaverryan Why?

Slide 61

Slide 61 text

TIP! Use OAuth? Or maybe a simple token-based authentication … sure, if you have bigger requirement, use something bigger @weaverryan

Slide 62

Slide 62 text

TIP! Don’t worry about versioning unless you really have the problem. @weaverryan

Slide 63

Slide 63 text

POST, PUT, Idempotency @weaverryan

Slide 64

Slide 64 text

Idempotency: ! Is it guaranteed to be safe if I accidentally make a request twice in a row? @weaverryan

Slide 65

Slide 65 text

POST: Not Idempotent
 PUT: Idempotent @weaverryan blah blah…

Slide 66

Slide 66 text

TIP! PUT if *both* of the following are true: 1) The request is idempotent ! 2) The URI is to the resource being updated … otherwise, use POST

Slide 67

Slide 67 text

@weaverryan /api/programmers POST Not Idempotent /api/programers/5 PUT /api/programmers/5/avatar PUT /api/programmers/5/sleep POST URI is not to resource being updated POST != idempotent, but making a request twice doesn’t *need* to have a side-effect

Slide 68

Slide 68 text

Editing PUT: Replace (nullify missing fields) ! PATCH: Update (send directions) @weaverryan

Slide 69

Slide 69 text

TIP! > Use either PATCH or PUT
 ! > Ignore how they’re supposed to work
 ! > Document clearly how you’re using them @weaverryan

Slide 70

Slide 70 text

@weaverryan GitHub API

Slide 71

Slide 71 text

REST ! Keep it Simple @weaverryan

Slide 72

Slide 72 text

1) Research Tools @weaverryan

Slide 73

Slide 73 text

2) Decide how you’ll test and generate your documentation before coding @weaverryan

Slide 74

Slide 74 text

3) Don’t let the Resource, Representation, State jargon confuse you @weaverryan

Slide 75

Slide 75 text

4) Add links to help your client, but don’t go for HATEOAS @weaverryan

Slide 76

Slide 76 text

5) Consistency is king 
 (use a serializer) @weaverryan

Slide 77

Slide 77 text

6) Use PUT if it follows the 2 rules, POST as the catch-all @weaverryan

Slide 78

Slide 78 text

And celebrate because you just survived your API! @weaverryan

Slide 79

Slide 79 text

Thanks! Ryan Weaver @weaverryan KnpUniversity.com PHP , Behat, Twig, OO, etc Tutorial Screencasts https://joind.in/12084