Slide 1

Slide 1 text

BUILDING GREAT APIs BEN RAMSEY True North PHP 2015

Slide 2

Slide 2 text

bram.se/tnphp-great-apis

Slide 3

Slide 3 text

HI, I’M BEN. I’m a web craftsman, author, and speaker. I build a platform for professional photographers at ShootProof. I enjoy APIs, open source software, organizing user groups, good beer, and spending time with my family. Nashville, TN is my home. ▸ Zend PHP Certification Study Guide ▸ Nashville PHP & Atlanta PHP user groups ▸ array_column() ▸ ramsey/uuid ▸ league/oauth2-client

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

AN API ENTHUSIAST? WHAT’S THAT? Eliza BUILDING GREAT APIs

Slide 6

Slide 6 text

IT’D BE LIKE SAYING I’M AN OOP ENTHUSIAST. Eliza

Slide 7

Slide 7 text

Somewhere along the way, we became pedantic about APIs.

Slide 8

Slide 8 text

It’s as if we wanted to invent a way for there to be someone wrong on the Internet.

Slide 9

Slide 9 text

APIs are important to what we do, and there’s no escaping them.

Slide 10

Slide 10 text

HOW LONG DOES THIS API NEED TO LAST? QUESTION ONE:

Slide 11

Slide 11 text

BUILDING GREAT APIs SCENARIO ONE: “Our client has an ad campaign, and they want to capture email addresses and postal codes and report on that information. We need to give them an endpoint to post data and another endpoint to pull the list. The campaign will only last a month. We won’t need it after that.”

Slide 12

Slide 12 text

BUILDING GREAT APIs SCENARIO ONE: BREAK DOWN ▸ Action 1: collect email address and postal code ▸ Action 2: return list of email addresses and postal codes ▸ Only needed for a month

Slide 13

Slide 13 text

BUILDING GREAT APIs POSSIBLE SOLUTION ▸ RPC (remote procedure call) ▸ saveCampaignData ▸ email: [email protected] ▸ postalCode: 12345 ▸ getCampaignData

Slide 14

Slide 14 text

POST /rpc.php HTTP/1.1 Host: api.example.com Content-Length: 125 { "method": "saveCampaignData", "params": { "email": "[email protected]", "postalCode": "12345" } } HTTP/1.1 200 OK Date: Sat, 10 Oct 2015 05:26:24 GMT Content-Length: 23 { "status": "success" }

Slide 15

Slide 15 text

Short-lived projects
 are rarely short-lived.

Slide 16

Slide 16 text

BUILDING GREAT APIs SCENARIO TWO: “Our client has decided they want to run the campaign a bit longer, and they also want to run a second campaign like it, but this time, they want to collect first and last names. Let’s just take that API you wrote and re-purpose it.”

Slide 17

Slide 17 text

BUILDING GREAT APIs SCENARIO TWO: CAVEATS ▸ It was specific to a single campaign ▸ It only collected email address and postal code ▸ The code is simple enough to make these changes and not break the existing campaign, but will we need to support more changes?

Slide 18

Slide 18 text

LEVEL 0: THE SWAMP OF POX Richardson Maturity Model

Slide 19

Slide 19 text

GREAT APIs USE RESOURCES AXIOM ONE:

Slide 20

Slide 20 text

BUILDING GREAT APIs BETTER SOLUTION USING RESOURCES ▸ Each submission creates a new record in the campaign ▸ Resources: campaign, record ▸ Ability to create a record in a campaign ▸ Ability to fetch all records in a campaign

Slide 21

Slide 21 text

GET /record/create?campaignID=o0zJeEcJ &[email protected]&postalCode=12345 HTTP/1.1 Host: api.example.com HTTP/1.1 200 OK Date: Sat, 10 Oct 2015 16:31:57 GMT Content-Length: 23 { "status": "success" }

Slide 22

Slide 22 text

GET /campaign/o0zJeEcJ HTTP/1.1 Host: api.example.com HTTP/1.1 200 OK Date: Sat, 10 Oct 2015 16:43:23 GMT Content-Length: 120 { "records": [ { "email": "[email protected]", "postalCode": "12345" } ] }

Slide 23

Slide 23 text

LEVEL 0: THE SWAMP OF POX LEVEL 1: RESOURCES Richardson Maturity Model

Slide 24

Slide 24 text

GREAT WEB APIs USE HTTP VERBS AXIOM TWO:

Slide 25

Slide 25 text

BUILDING GREAT APIs BETTER SOLUTION USING HTTP VERBS ▸ Use proper HTTP semantics for resources ▸ POST to create a new record, GET to fetch a campaign ▸ What else can we do with that campaign resource? ▸ Create new campaigns with POST ▸ Update campaigns with PUT ▸ What about the record? ▸ Fetch an individual record with GET

Slide 26

Slide 26 text

POST /campaign HTTP/1.1 Host: api.example.com Content-Length: 37 { "name": "My Awesome Campaign" } HTTP/1.1 200 OK Date: Sat, 10 Oct 2015 17:14:11 GMT Content-Length: 67 { "campaignId": "o0zJeEcJ", "name": "My Awesome Campaign" }

Slide 27

Slide 27 text

PUT /campaign/o0zJeEcJ HTTP/1.1 Host: api.example.com Content-Length: 139 { "name": "My Awesome Campaign", "startDate": "Sun, 06 Sep 2015 18:12:47 +0000", "endDate": "Tue, 06 Oct 2015 18:13:06 +0000" } HTTP/1.1 200 OK Date: Sat, 10 Oct 2015 17:22:04 GMT Content-Length: 169 { "campaignId": "o0zJeEcJ", "name": "My Awesome Campaign", "startDate": "Sun, 06 Sep 2015 18:12:47 +0000", "endDate": "Tue, 06 Oct 2015 18:13:06 +0000" }

Slide 28

Slide 28 text

POST /record HTTP/1.1 Host: api.example.com Content-Length: 91 { "campaignID": "o0zJeEcJ", "email": "[email protected]", "postalCode": "12345" } HTTP/1.1 200 OK Date: Sat, 10 Oct 2015 17:28:45 GMT Content-Length: 119 { "recordId": "5s7ytJlT", "campaignID": "o0zJeEcJ", "email": "[email protected]", "postalCode": "12345" }

Slide 29

Slide 29 text

GET /record/5s7ytJlT HTTP/1.1 Host: api.example.com HTTP/1.1 200 OK Date: Sat, 10 Oct 2015 17:29:31 GMT Content-Length: 119 { "recordId": "5s7ytJlT", "campaignID": "o0zJeEcJ", "email": "[email protected]", "postalCode": "12345" }

Slide 30

Slide 30 text

Now, our API is starting to look RESTful!

Slide 31

Slide 31 text

LEVEL 0: THE SWAMP OF POX LEVEL 1: RESOURCES LEVEL 2: HTTP VERBS Richardson Maturity Model

Slide 32

Slide 32 text

WHO WILL USE THIS API? QUESTION TWO:

Slide 33

Slide 33 text

BUILDING GREAT APIs SCENARIO THREE: “Our client likes using our API. They want to know if they can use it to create and manage an indefinite amount of campaigns. Oh—I almost forgot—we have another client who wants to use our API to manage campaigns, too. Can we do that?” Why, yes! We can.

Slide 34

Slide 34 text

BUILDING GREAT APIs SCENARIO THREE: CONSIDERATIONS ▸ Authentication ▸ Stateless authentication with keys, tokens, & shared secrets ▸ As more clients want access to your API, how do they know what the endpoints are? ▸ Up until now, it’s through documentation ▸ Is there a better way?

Slide 35

Slide 35 text

GREAT WEB APIs USE HYPERMEDIA AXIOM THREE:

Slide 36

Slide 36 text

BUILDING GREAT APIs BETTER SOLUTION USING HYPERMEDIA ▸ Use links to provide relationships between resources ▸ Use media types to describe how to process a representation

Slide 37

Slide 37 text

POST /campaign HTTP/1.1 Host: api.example.com Accept: application/hal+json Content-Type: application/json Content-Length: 37 { "name": "My Awesome Campaign" } HTTP/1.1 201 Created Date: Sat, 10 Oct 2015 17:45:27 GMT Content-Type: application/hal+json Content-Length: 838 Location: https://api.example.com/campaign/o0zJeEcJ

Slide 38

Slide 38 text

{ "_links": { "self": { "href": "https://api.example.com/campaign/o0zJeEcJ" }, "curies": [{ "name": "ex", "href": "https://api.example.com/docs/rels/{rel}", "templated": true }], "ex:campaigns": { "href": "https://api.example.com/campaign/" }, "ex:records": { "href": "https://api.example.com/record/" } }, "name": "My Awesome Campaign", "_embedded": { "ex:record": [{ "_links": { "self": { "href": "https://api.example.com/record/5s7ytJlT" }, "ex:campaign": { "href": "https://api.example.com/campaign/o0zJeEcJ" } }, "email": "[email protected]", "postalCode": "12345" }] } }

Slide 39

Slide 39 text

LEVEL 0: THE SWAMP OF POX LEVEL 1: RESOURCES LEVEL 2: HTTP VERBS LEVEL 3: HYPERMEDIA Richardson Maturity Model

Slide 40

Slide 40 text

Hypermedia as the engine of application state.

Slide 41

Slide 41 text

WILL THE API EVER NEED TO CHANGE? QUESTION THREE:

Slide 42

Slide 42 text

Yes. Your API will change.

Slide 43

Slide 43 text

GREAT APIs ARE BUILT FOR CHANGE AXIOM FOUR:

Slide 44

Slide 44 text

BUILDING GREAT APIs EVOLVABILITY ▸ If we change the URLs, will we break clients? ▸ If we add or remove properties, will we break clients? ▸ If we change the input values we accept, will we break clients?

Slide 45

Slide 45 text

Versioning in APIs exists because we’re afraid of breaking clients.

Slide 46

Slide 46 text

https://api.example.com/v2/campaign

Slide 47

Slide 47 text

Hypermedia resolves the versioning problem.

Slide 48

Slide 48 text

BUILDING GREAT APIs VERSIONING & CONTENT NEGOTIATION ▸ I can change URLs and nothing breaks ▸ I can add properties and nothing breaks ▸ If I remove properties or require new inputs, I can use content-negotiation to version the API: ▸ application/vnd.example+json;version=2 ▸ Everybody’s happy

Slide 49

Slide 49 text

REST is essentially concerned
 with the evolvability of a
 network-based application.

Slide 50

Slide 50 text

GREAT APIs ARE BUILT TO LAST AXIOM FIN:

Slide 51

Slide 51 text

If you think you have control over the system or aren’t interested in evolvability, don’t waste your time arguing about REST. Roy T. Fielding BUILDING GREAT APIs

Slide 52

Slide 52 text

THANK YOU. ANY QUESTIONS? If you want to talk more, feel free to contact me. benramsey.com @ramsey github.com/ramsey [email protected] joind.in/15761 Ŏ This presentation was created using Keynote. The text is set in DIN Alternate and Avenir Next. The source code is set in Source Code Pro. The iconography is provided by Font Awesome. Unless otherwise noted, all photographs are used by permission under a Creative Commons license. Please refer to the Photo Credits slide for more information. Building Great APIs Copyright © 2015 Ben Ramsey This work is licensed under Creative Commons Attribution-ShareAlike 4.0 International. For uses not covered under this license, please contact the author. Ramsey, Ben. “Building Great APIs” True North PHP. Microsoft Canada, Mississauga. 7 Nov. 2015. Conference presentation.

Slide 53

Slide 53 text

Photo Credits 1. “Sunset at Mid State Fair” by Howard Ignatius 2. Photo of Ben Ramsey by Eli White 3. “Magical Merry Go Round” by Floyd Stewart 4. “Dusk Lemonade Stand” by Kellar Wilson 5. “The Wheel” by Aristocrats-hat 6. “Playing With My New Camera” by Mark Walley 7. “Merry-go-round” by mafleen 8. “Caramel Apples” by m01229 9. “Elephant Ears + spinning ride” by m01229 10. “Garden of Unearthly Delights - sideshows” by Heather

Slide 54

Slide 54 text

Photo Credits 11. “The Magnificent Machines of Yeserday (House on the Rock)” by Justin Kern 12. “Mr. Dark’s Ticket Booth (House on the Rock)” by Justin Kern 13. “The Ultimate Carnival” by Trey Ratcliff 14. “Marenghi Orchestrion at the Great Dorset Steam Fair” by Anguskirk