Slide 1

Slide 1 text

HTTP/2 Server Push
 and the rise of client-driven REST APIs

Slide 2

Slide 2 text

@dunglas - vulcain.rocks Kévin Dunglas ❏ Founder of Les-Tilleuls.coop ❏ Creator of Vulcain.rocks, Mercure.rocks, API Platform… ❏ Symfony Core Team Member @dunglas @ .social

Slide 3

Slide 3 text

@dunglas - vulcain.rocks API, cloud, PHP and JS experts ✊ Self-managed, 100% employee-owned 45 people, 1,000% growth in 6 years [email protected] Les-Tilleuls.coop

Slide 4

Slide 4 text

@dunglas - vulcain.rocks What’s REST?

Slide 5

Slide 5 text

@dunglas - vulcain.rocks « REST was developed […] primarily as a means for communicating Web concepts as we wrote the HTTP/1.0 specification and the initial HTTP/1.1 proposal. »
 - Roy T. Fielding

Slide 6

Slide 6 text

@dunglas - vulcain.rocks REST: the Architectural Style of the Web ❏ client-server ❏ resource oriented ❏ stateless ❏ cacheable by clients and intermediaries ❏ layered (gateways and proxies) ❏ uniform interface (URI, HATEOAS…)

Slide 7

Slide 7 text

RESTful Web Services

Slide 8

Slide 8 text

@dunglas - vulcain.rocks REST Performance

Slide 9

Slide 9 text

@dunglas - vulcain.rocks REST Performance ❏ REST is designed to solve performance and scalability problems at internet-scale ❏ REST relies on a powerful caching model: clients and intermediates can cache ❏ HTTP implements this model © Google

Slide 10

Slide 10 text

@dunglas - vulcain.rocks The Under-Fetching and the N+1 Problems Not fetching enough data initially forces to issue subsequent requests, so creates waterfalls and increase latency. © Expedia Group

Slide 11

Slide 11 text

@dunglas - vulcain.rocks The Over-Fetching Problem Generating and fetching too much data (data not used by clients) wastes bandwidth and computation power.

Slide 12

Slide 12 text

GraphQL: an Alternative to REST « Fixing » its Perf Issues (among other things…)

Slide 13

Slide 13 text

@dunglas - vulcain.rocks HTTP/2+

Slide 14

Slide 14 text

@dunglas - vulcain.rocks HTTP/2: Making the Web Faster ❏ Binary protocol, multiplexing, prioritization ❏ Server Push of resources ❏ Headers compression ❏ HTTP/3: good bye TCP (perf, again)

Slide 15

Slide 15 text

@dunglas - vulcain.rocks HTTP/2: Multiplexing © Narayan Prusty

Slide 16

Slide 16 text

@dunglas - vulcain.rocks HTTP/2: Server Push

Slide 17

Slide 17 text

@dunglas - vulcain.rocks HTTP/2 global support:
 95% of all internet users

Slide 18

Slide 18 text

@dunglas - vulcain.rocks CloudWays Benchmark

Slide 19

Slide 19 text

@dunglas - vulcain.rocks Fast and idiomatic client-driven REST APIs Introducing Vulcain

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

@dunglas - vulcain.rocks Pushing Relations

Slide 22

Slide 22 text

@dunglas - vulcain.rocks Consuming Pushes in JavaScript const outboxResp = await fetch( "/outbox", { headers: { Preload: "/orderedItems/*/object" } } ); const outbox = await outboxResp.json(); outboxJSON.orderedItems.forEach(async activityURL => { // Returns immediately,
 // the resource has been pushed and is already in the push cache const activityResp = await fetch(activityURL); const activity = await activityResp.json(); // Returns immediately too const statusResp = await fetch(activity.object); // Do something with the status response... });

Slide 23

Slide 23 text

@dunglas - vulcain.rocks Benefits ❏ Fixes the under-fetching and N+1 problems ❏ Resources are downloaded in parallel (multiplexing) ❏ Granular HTTP cache (download only what isn’t in cache) ❏ Respects REST principles ❏ Leverages all features of the HTTP protocol ❏ cache, authorization, content negotiation, extensibility…

Slide 24

Slide 24 text

@dunglas - vulcain.rocks Filtering Resources

Slide 25

Slide 25 text

@dunglas - vulcain.rocks Other Capabilities ❏ Selector negotiation: ❏ extended JSON Pointer, XPath, CSS selectors, JMESPath… ❏ Support using Link preload headers and103 Early Hints as a fallback (cross-domain resources, HTTP/1…) ❏ Use query parameters instead of HTTP headers ❏ Support non-hypermedia APIs through OpenAPI

Slide 26

Slide 26 text

@dunglas - vulcain.rocks The Vulcain Gateway Server

Slide 27

Slide 27 text

@dunglas - vulcain.rocks The Vulcain Gateway Server ❏ Instantly turns any existing hypermedia or non-hypermedia API into a Vulcain-enabled API ❏ Gateway server (plug’n’play network intermediate) ❏ Free software (open source) ❏ Fast, written in Go ❏ Easy to install (static binary, Docker image) ❏ Best performance: implement the protocol directly at the app server layer

Slide 28

Slide 28 text

@dunglas - vulcain.rocks Starting the Gateway Server

Slide 29

Slide 29 text

@dunglas - vulcain.rocks Mapping a « Legacy » API

Slide 30

Slide 30 text

@dunglas - vulcain.rocks Mapping a « Legacy » API # openapi.yaml openapi: 3.0.0 # ... paths: '/books/{id}': get: # ... responses: default: links: author: operationId: getAuthor parameters: id: '$response.body#/author' '/authors/{id}': get: operationId: getAuthor responses: default: # ... // /books/1984 { "title": "1984", "author": 1 // Not an URI } // /authors/1 { "givenName": "George", "familyName": "Orwell" }

Slide 31

Slide 31 text

@dunglas - vulcain.rocks So… What About GraphQL?

Slide 32

Slide 32 text

@dunglas - vulcain.rocks Vulcain vs GraphQL: Performance ❏ Unlike GraphQL, Vulcain sends each pushed resource in a separate HTTP/2 stream (multiplexing): related resources are sent in parallel ❏ Embedding resources is a forced push: the client receive the full JSON documents, even if it already has some parts of it ❏ With Vulcain, clients can cancel the push of resources they already have, saving bandwidth and improving performance

Slide 33

Slide 33 text

@dunglas - vulcain.rocks But GraphQL is More Than That! ❏ Query Language ❏ Type System ❏ Introspection ❏ Subscriptions ❏ Great tooling

Slide 34

Slide 34 text

@dunglas - vulcain.rocks Type System and Introspection REST has that too… and a bit more! ❏ JSON-LD: internet-scale type system,
 built on top of RDF, W3C ❏ Hydra: hypermedia introspection system,
 built on top of JSON-LD, W3C ❏ OpenAPI: type system and introspection

Slide 35

Slide 35 text

@dunglas - vulcain.rocks { "@context": "https://www.w3.org/ns/activitystreams", "type": "Person", "id": "https://social.example/alyssa/", "name": "Alyssa P. Hacker", "preferredUsername": "alyssa", "summary": "Lisp enthusiast hailing from MIT", "inbox": "https://social.example/alyssa/inbox/", "outbox": "https://social.example/alyssa/outbox/", "followers": "https://social.example/alyssa/followers/", "following": "https://social.example/alyssa/following/", "liked": "https://social.example/alyssa/liked/" }

Slide 36

Slide 36 text

@dunglas - vulcain.rocks Subscriptions https://mercure.rocks

Slide 37

Slide 37 text

@dunglas - vulcain.rocks Tooling ❏ GraphQL provides great client-side tooling and an unified Developer Experience, REST is still behind ❏ But because GraphQL uses HTTP as a black box: ❏ HTTP Cache servers (Varnish, Nginx…) ❏ standard WAF (ModSecurity…) ❏ HTTP logs analyzer (GoAccess, AWStats…) ❏ API Gateways (Kong, Gravitee…) are almost useless

Slide 38

Slide 38 text

@dunglas - vulcain.rocks Tooling REST also has modern, easy to use client-side and server-side tooling: ❏ API Platform (PHP & JS): create JSON-LD APIs and smart React & Vue PWA, admin UIs, etc… in minutes! ❏ Graphiti (Ruby On Rails): create REST APIs in minutes ❏ Zeit’s SWR: React Hooks library for HTTP APIs leveraging concurrent rendering (perfect Vulcain’s companion) Vulcain works out of the box with all these tools!

Slide 39

Slide 39 text

@dunglas - vulcain.rocks Using GraphQL to Query a Vulcain Server ❏ GraphQL is a convenient Query Language for APIs ❏ Write GraphQL queries client-side, and benefit from all the GQL ecosystem ❏ Use apollo-link-rest to convert the GQL query in a single REST+Vulcain request to the server Best of both worlds?

Slide 40

Slide 40 text

@dunglas - vulcain.rocks Save the Web:
 Stop Centralizing!

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

@dunglas - vulcain.rocks

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

@dunglas - vulcain.rocks « The Web is intended to be an Internet-scale distributed hypermedia system […]. The Internet is about interconnecting information networks across multiple organizational boundaries. »
 - Roy T. Fielding

Slide 45

Slide 45 text

@dunglas - vulcain.rocks The Threat of Data Centralization ❏ Facebook, Microsoft, Google, Apple… participated to NSA’s PRISM global mass surveillance program ❏ Cambridge Analytica manipulated the US election using Facebook data ❏ Facebook blocks pages of Kurdish organizations fighting ISIS ❏ GitHub blocks all Iranian users, including famous OSS contributors ❏ GitHub banned Tsunami Democràtic's app (pro Catalan-independence) Data centralization is harmful!

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

@dunglas - vulcain.rocks REST /
 Linked Data GraphQL server Origin Scientific community, to serve humanity Facebook, to serve its business Data access « Internet as a global database » Centralized information silos Interoperability Global and built-in Partial Best suited for Distributed systems Public APIs (« Open Data ») The World Wide Web Centralized systems Internal APIs

Slide 48

Slide 48 text

@dunglas - vulcain.rocks // https://social.example/alyssa/posts/123 { "@context": "https://www.w3.org/ns/activitystreams", "type": "Note", // Not possible with a GraphQL server "to": ["https://chatty.example/ben/"], // reference to an external organization "attributedTo": "https://social.example/alyssa/", "content": "Say, did you finish reading that book I lent you?" } The power of Vulcain: GET https://social.example/alyssa/posts/123 Preload: /to Fields: /to, /content // Some hope for GraphQL? GraphQL-LD, HyperGraphQL: GQL as a query language for RDF

Slide 49

Slide 49 text

The Rise of the Dweb

Slide 50

Slide 50 text

@dunglas - vulcain.rocks The Rise of the Dweb REST, JSON-LD, schema.org, RDF, ActivityPub… ❏ Solid (by T. Berners-Lee): web decentralization, privacy by design ❏ : federated social network ❏ Mobilizon: federated Meetup-like ❏ PeerTube: federated video-streaming service ❏ NextCloud: federated file sharing service Vulcain works out of the box with all of them!

Slide 51

Slide 51 text

@dunglas - vulcain.rocks And What About Symfony?!

Slide 52

Slide 52 text

@dunglas - vulcain.rocks Vulcain, Symfony and API Platform The project: ❏ an app to send feedback to speakers, as in Lisbon 2018 The stack: ❏ Symfony + API Platform ❏ JSON-LD ❏ Varnish ❏ Vulcain

Slide 53

Slide 53 text

@dunglas - vulcain.rocks The API Platform Distribution ❏ PHP + Symfony + API Platform ❏ Vulcain (master branch only) ❏ Varnish ❏ Postgres ❏ Docker and Kubernetes config github.com/dunglas/demo-vulcain-api-platform

Slide 54

Slide 54 text

@dunglas - vulcain.rocks MakerBundle FTW!

Slide 55

Slide 55 text

@dunglas - vulcain.rocks Our Vulcain API is Ready! A fully-featured API for the Dweb: ❏ JSON-LD + Hydra + schema.org ❏ Vulcain ❏ Varnish ❏ Mercure, auth, pagination, filters, validation, test framework, admin, React/Vue.js/Next.js generators…

Slide 56

Slide 56 text

@dunglas - vulcain.rocks Benchmark ❏ Inject fixtures (using Alice) ❏ 10 conferences ❏ 100 sessions ❏ 100 feedback ❏ Fetch all the resources client-side

Slide 57

Slide 57 text

@dunglas - vulcain.rocks Benchmark // Load ALL data from the API // Simulate more data dependencies than they really exist
 // to increase the waterfall effect console.time('download'); const conferences = await fetchJson('/conferences', { headers: { Preload: ‘/hydra:member/*/@id/ sessions/*/feedback/*' }}); for (const conferenceRel of conferences['hydra:member']) { const conference = await fetchJson(conferenceRel['@id']); // Fetch sessions for (const sessionURL of conference.sessions) { const session = await fetchJson(sessionURL); // Fetch feedback for (const feedbackURL of session.feedback) { const feedback = await fetchJson(feedbackURL) } } } console.timeEnd('download');

Slide 58

Slide 58 text

@dunglas - vulcain.rocks Results: Vulcain kills the Waterfall effect ❏ No Varnish, No Vulcain: 22,152 ms ❏ No Varnish, Vulcain: 9,704 ms ❏ Varnish, No Vulcain: 783 ms ❏ Varnish + Vulcain: 524ms ❏ Vulcain is 2.3x faster than API Platform without Vulcain ❏ Varnish is 28x faster than API Platform without Varnish ❏ The combination of Varnish and Vulcain is 42x faster than API Platform without Varnish, and without Vulcain ❏ The combination of Varnish and Vulcain is 1.5x faster than Varnish alone!

Slide 59

Slide 59 text

Without Vulcain: 10.4s With Vulcain: 4.72s

Slide 60

Slide 60 text

@dunglas - vulcain.rocks github.com/dunglas/demo-vulcain-api-platform Contains a benchmark using Symfony HttpClient! « All data retrieved in 0.85s »

Slide 61

Slide 61 text

@dunglas - vulcain.rocks Summary Vulcain is: ❏ Fast (faster than GraphQL and JSON:API includes) ❏ Designed for the open web and interoperability at Internet-scale ❏ Easy to deploy ❏ Compatible with most existing tools ❏ Swagger/OpenAPI, log analyzers, Varnish, WAF, RDF… ❏ Can be supported in minutes by any web API ❏ including legacy RESTish APIs thanks to its OpenAPI support ❏ You can even use GraphQL to query a Vulcain API! Give it a try!

Slide 62

Slide 62 text

Thank you! vulcain.rocks - @dunglas - les-tilleuls.coop and come at our booth!