Slide 1

Slide 1 text

Ben Ramsey, PHP Tek, 21 May 2025 Return to REST

Slide 2

Slide 2 text

We’re talking about APIs.

Slide 3

Slide 3 text

APIs: Fun for mash-ups circa 2008.

Slide 4

Slide 4 text

APIs: Super-big business in 2025.

Slide 5

Slide 5 text

The world can’t work (together) without APIs.

Slide 6

Slide 6 text

HTTP APIs won.

Slide 7

Slide 7 text

We’re talking about APIs, but

Slide 8

Slide 8 text

Specifically, we’re talking about REST APIs.

Slide 9

Slide 9 text

Web 2.0 When REST was hot stu ff .

Slide 10

Slide 10 text

What happened? Why don’t we talk about REST anymore?

Slide 11

Slide 11 text

ME REST GRAPHQL

Slide 12

Slide 12 text

GraphQL is really popular. What does it have that REST doesn’t? GRAPHQL

Slide 13

Slide 13 text

Representational State Transfer

Slide 14

Slide 14 text

Representational what now?

Slide 15

Slide 15 text

REST An architectural style that de fi nes six constraints.

Slide 16

Slide 16 text

1. Client/server

Slide 17

Slide 17 text

2. Stateless

Slide 18

Slide 18 text

3. Cache

Slide 19

Slide 19 text

• Identi fi cation of resources • Manipulation of resources through representations • Self-descriptive messages • Hypermedia as the engine of application state 4. Uniform interface

Slide 20

Slide 20 text

5. Layered system

Slide 21

Slide 21 text

6. Code on demand (Optional)

Slide 22

Slide 22 text

Representational State Transfer 1. Client/server 2. Stateless 3. Cache 4. Uniform interface 5. Layered system 6. Code on demand REST

Slide 23

Slide 23 text

Cool, Ben.

Slide 24

Slide 24 text

So, now what?

Slide 25

Slide 25 text

What exactly does that get me?

Slide 26

Slide 26 text

An architecture that is… • Loosely coupled • Simple • Evolvable • Portable • Reliable • Scalable REST

Slide 27

Slide 27 text

If it’s supposed to be so simple, why is it so hard?!

Slide 28

Slide 28 text

simple != easy

Slide 29

Slide 29 text

• We’re humans • We’re lazy • We need this yesterday. • We don’t plan for the future. • REST requires investments. • We all suck.

Slide 30

Slide 30 text

GraphQL

Slide 31

Slide 31 text

ME REST GRAPHQL

Slide 32

Slide 32 text

GraphQL

Slide 33

Slide 33 text

• Reduces number of network requests and amount of data transferred • From a company whose motto was once “move fast and break things” • The primary trade-o ff : extreme tight coupling GraphQL

Slide 34

Slide 34 text

ME REST GRAPHQL

Slide 35

Slide 35 text

REST story time…

Slide 36

Slide 36 text

REST

Slide 37

Slide 37 text

Level 0: The Swamp of POX

Slide 38

Slide 38 text

HTTP/1.1 200 OK Date: Sat, 10 Oct 2024 16:31:57 GMT Content-Length: 23 { "status": "success" } POST /rpc.php HTTP/1.1 Host: api.example.com Content-Length: 125 { "method": "saveCampaignData", "params": { "email": "[email protected]", "postalCode": "12345" } } Request Response

Slide 39

Slide 39 text

Level 0: The Swamp of POX Level 1: Resources

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

Level 0: The Swamp of POX Level 1: Resources Level 2: HTTP Verbs

Slide 43

Slide 43 text

• 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 • Use PATCH to partially update a record

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

HTTP/1.1 200 OK Date: Sat, 10 Oct 2024 17:22:04 GMT Content-Length: 173 { "campaignId": "o0zJeEcJ", "name": "Totally Rad Campaign", "startDate": "2015-09-06T18:12:47+00:00", "endDate": "2015-10-06T18:13:06+00:00" } PUT /campaign/o0zJeEcJ HTTP/1.1 Host: api.example.com Content-Length: 143 { "campaignId": "o0zJeEcJ", "name": "Totally Rad Campaign", "startDate": "2015-09-06T18:12:47+00:00", "endDate": "2015-10-06T18:13:06+00:00" } Request Response

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

HTTP/1.1 200 OK Date: Sat, 10 Oct 2024 17:28:45 GMT Content-Length: 123 { "recordId": "5s7ytJlT", "campaignID": "o0zJeEcJ", "email": "[email protected]", "postalCode": "12345" } PATCH /record/5s7ytJlT HTTP/1.1 Host: api.example.com Content-Length: 38 { "email": "[email protected]" } Request Response

Slide 49

Slide 49 text

Level 0: The Swamp of POX Level 1: Resources Level 2: HTTP Verbs Level 3: Hypermedia

Slide 50

Slide 50 text

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

Slide 51

Slide 51 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 52

Slide 52 text

Live, Laugh, Rest

Slide 53

Slide 53 text

HATEOAS

Slide 54

Slide 54 text

Hypermedia As The Engine Of Application State H A T E O A S

Slide 55

Slide 55 text

In a nutshell • Use links to provide relationships between resources • Use media types to describe how to process a representation Hypermedia

Slide 56

Slide 56 text

Benefits • Clients discover locations and operations • Link relations express possible options • URLs can change • Work fl ow is abstracted • Media type can be versioned • Clients do not break if the implementation is updated! Hypermedia

Slide 57

Slide 57 text

It answers these questions • How does a client know what to do with resources? • How do you go to the “next” operation? • What are the URLs for creating subordinate resources? • Where is the contract for the service? Hypermedia

Slide 58

Slide 58 text

Make the most of HTTP

Slide 59

Slide 59 text

• Use HTTP methods for the purpose they were created: • GET, POST, PUT, PATCH, DELETE, BREW… • Uniquely identify each resource with a URI. • Be self-documenting through headers (e.g., Accept, Allow, Link, etc.) • Use hypermedia (links)! • Put thought into your media types.

Slide 60

Slide 60 text

HTTP/1.1 200 OK Date: Sat, 10 Oct 2024 17:28:45 GMT Accept: application/hal+json Allow: GET, PUT, PATCH, DELETE, OPTIONS, HEAD Link: ; rel="self" Link: ; rel="collection" Link: ; rel="https://example.com/rel/campaign" OPTIONS /record/5s7ytJlT HTTP/1.1 Host: api.example.com Request Response

Slide 61

Slide 61 text

HTTP/1.1 200 OK Date: Sat, 10 Oct 2024 17:28:45 GMT Accept: application/hal+json Allow: GET, POST, OPTIONS, HEAD Link: ; rel="self" Link: ; rel="start" Link: ; rel="next" Link: ; rel="last" OPTIONS /record HTTP/1.1 Host: api.example.com Request Response

Slide 62

Slide 62 text

Our API is self-documenting!

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

BUT IT’S NOT RESTful IF YOU… ENOUGH!

Slide 65

Slide 65 text

Evolvability is what we want.

Slide 66

Slide 66 text

• 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 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

Hypermedia resolves the versioning problem.

Slide 71

Slide 71 text

• 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. (Maybe?)

Slide 72

Slide 72 text

HTTP/1.1 200 OK Date: Sat, 10 Oct 2024 17:28:45 GMT Accept: application/vnd.example+json; q=0.8, application/vnd.example+json; version=2; q=0.9, application/vnd.example+json; version=3 Allow: GET, PUT, PATCH, DELETE, OPTIONS, HEAD Link: ; rel="self" Link: ; rel="collection" Link: ; rel="https://example.com/rel/campaign" OPTIONS /record/5s7ytJlT HTTP/1.1 Host: api.example.com Request Response

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

Testing DSL for REST APIs • Express your API tests in a natural and intuitive way • Facilitates and encourages TDD and BDD for APIs • Supports validation with JSON Schema • rest-certain/rest-certain • Ports of REST Assured from Java to PHP REST Certain

Slide 75

Slide 75 text

Thank you! Keep in touch       ben.ramsey.dev phpc.social/@ramsey github.com/ramsey speakerdeck.com/ramsey www.linkedin.com/in/benramsey [email protected] bram.se/phptek-rest     

Slide 76

Slide 76 text

Resources • IANA HTTP Method Registry • IANA HTTP Field Name Registry • IANA Link Relations Registry • IANA Media Types Registry • RFC 9110: HTTP Semantics • RFC 5789: PATCH Method for HTTP • RFC 8288: Web Linking • Hypermedia Application Language (HAL) • Architectural Styles and the Design of Network-based Software Architectures, Roy T. Fielding

Slide 77

Slide 77 text

Photo Credits • Clear Inner Vision. "Restful Summer." CC BY-NC-ND 2.0. • Wouter de Bruijn. "Day 90." CC BY-NC-SA 2.0. • George Rosema. "Spider Web in morning dew." Unsplash License. • Shannon Potter. Untitled. Unsplash License. • Ibrahim Fareed. Untitled. Unsplash License. • Alice Olivier. "Popular Web 2.0 Logos." CC BY 3.0. • Carlos Torres. "From the plane." Unsplash License. • Ante Hamersmit. "Man sitting on a wooden bridge." Unsplash License. • Jacek Smoter. "Forest in central Poland." Unsplash License. • Artem Kniaz. "picturesque colorful autumn landscape….” Unsplash License. • Todd Trapani. "Up early watching the sun rise along the beach." Unsplash License. • Kaupo Kalda. "Sleepy sunset." Unsplash License. • Meina Yin. Untitled. Unsplash License. • Nathan Dumlao. Untitled. Unsplash License. • Rythik. "Silhouette." Unsplash License. • Shirley Chen. Untitled. Unsplash License. • Claudio Schwarz. Untitled. Unsplash License. • Chris Lynch. "Man sleeping on couch." Unsplash License. • Richard Bell. Untitled. Unsplash License. • Richard Beatson. Untitled. Unsplash License. • David Clode. "I am very glad that I got some photos…." Unsplash License. • Kym MacKinnon. "Ombre Sunrise Re fl ections." Unsplash License. • Jacqueline O'Gara. Untitled. Unsplash License. • Tim Johnson. Untitled. Unsplash License. • Howei Wang. Untitled. Unsplash License. • Xavier von Erlach. "The sky above the Swiss Alps after midnight." Unsplash License.