nat welch / srecon'19 americas - usenix...proprietary + confidential most graphql endpoints...

39
Proprietary + Confidential Nat Welch / SRECon'19 Americas 2019-03-26 nat.wiki/srecon-graphql

Upload: others

Post on 23-May-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

Nat Welch / SRECon'19 Americas2019-03-26nat.wiki/srecon-graphql

Page 2: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

Nat Welch

Proprietary + Confidential

Nat Welch is an SRE based in Brooklyn, NY, and the author of "Real World SRE".

He currently works for Google on the Customer Reliability Engineering team.

In the past, he has worked for First Look Media, Hillary for America, iFixit, and others.

@icco

Page 3: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

Agenda

● What is GraphQL

● Why use GraphQL

● Using GraphQL in production

● Current state of the ecosystem

Page 4: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

What is GraphQL?

Page 5: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

Source: https://facebook.github.io/graphql/June2018/#sec-Overview

GraphQL is a query language designed to build client applications by providing [...] a system for describing their data requirements and interactions.

GraphQL June 2018 Spec

”Facebook

Page 6: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

GraphQL is a specification which defines a schema on an API server, which validates client calls.

Page 7: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

GraphQL is an application layer. GraphQL does not define how data is stored or queried from the source.

Page 8: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

$ curl -d ‘’ \ https://graphql.natwelch.com/graphql

Page 9: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

The JSON response to GraphQL queries mirror each other. This can be nested as deep as the client wants.

Page 10: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

The shape of the request defines the shape of the response.

Page 11: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

query { time}

Page 12: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

{ "data": { "time": "2019-03-24T21:32:22Z" }}

Page 13: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

query { post(id: "691") { title }}

Page 14: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

{ "data": { "post": { "title": "What's making me happy" } }}

Page 15: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

query { post(id: "691") { related(input: { limit: 7 }) { id } }}

Page 16: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

{ "data": { "post": { "related": [ { "id": "457" }, { "id": "663" },

Page 17: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

GraphQL is strongly typed. The schema defines types and object relationships.

Page 18: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

type Query { time: Time post(id: ID): Post}

Page 19: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

type Post { title: String related(input: Limit): [Post]}

Page 20: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

"""Time is a datetime scalar with timezone."""scalar Time

Page 21: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

GraphQL has documentation as a first class citizen. Clients can ask servers for information about schema, including documentation and types.

Page 22: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

query { __type(name: "Time") { description }}

Page 23: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

{ "data": { "__type": { "description": "Time is a datetime scalar with timezone." } }}

Page 24: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

"""A post is an individual post in the blog."""type Post implements Linkable { title: String! "A list of related posts." related(input: Limit): [Post]!}

Page 25: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + Confidential

Source: https://github.com/prisma/graphql-playground

Page 26: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

Why?

Page 27: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

graphql

graphql

graphql

graphql

users

External API

Mobile

Browser

CLI

Database

Internal Service

CLIENTS LOAD BALANCED REPLICAS BACKENDS

Page 28: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

● Simplify client development

● Simplify backend versioning

● Separate concerns between frontend and backend

● Lower dependencies of client launches

● Single front-end that is accessible to the public

Why

Page 29: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

● Media Companies

○ New York Times1, First Look Media2, Major League Soccer3

● Mobile Apps

○ Artsy4, Yelp5

● Complex Datasets

○ Github6, Shopify7, Fabric8

Use Cases

1. https://open.nytimes.com/react-relay-and-graphql-under-the-hood-of-the-times-website-redesign-22fb62ea97642. https://code.firstlook.media/welcome3. https://labs.mlssoccer.com/implementing-graphql-at-major-league-soccer-ff0a002b20ca4. http://artsy.github.io/blog/2016/11/02/improving-page-speed-with-graphql/5. https://engineeringblog.yelp.com/2017/05/introducing-yelps-local-graph.html 6. https://githubengineering.com/the-github-graphql-api/ 7. https://help.shopify.com/en/api/custom-storefronts/storefront-api/graphql 8. https://fabric.io/blog/building-fabric-mission-control-with-graphql-and-relay

Page 30: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

Production Problems

Page 31: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

● Really easy to make resolvers that make a lot of queries.

● Use some sort of project like dataloader1 that minimizes or unifies

queries to backends.

Dumb Resolvers

1. https://github.com/facebook/dataloader

Page 32: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

● Similar to dumb resolvers, it is really easy to write a system that turns

one graphql request into thirty backend requests.

● One metric to monitor is backend requests per query. If that spikes, or

goes out, you may need to refactor your schema.

Fan Out

Page 33: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

It is really easy to make complex requests. If you can, put hard limits on query complexity. Otherwise you could find people sending abusive queries.

Query Complexityquery { posts({limit: 1000}) { related { title uri related { title uri related { ... } } } }}

Page 34: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

● Really easy to make gigantic requests

● Also easy to make gigantic responses

Request Size

Page 35: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

● Most GraphQL endpoints use POST which is not cached by CDNs by default

● Persisted queries

○ Apollo Automatic Persistent Queries (on-the-fly)1

○ Relay v3 Persisted Queries (pre-compiled)2

● Also can cache in client code, not always relying on cache headers

Caching

1. https://github.com/apollographql/apollo-link-persisted-queries 2. https://facebook.github.io/relay/docs/en/persisted-queries.html

Page 36: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

Ecosystem

Page 37: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

Different Directions, Same Goal

Schema First

Group of frameworks focused on generating code

based off of schema or requiring schema to be

written.

Code First

Group of frameworks focusing on defining

backends and resolvers and auto-generating schema

from that.

Page 38: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

Some interesting things to look into

● Apollo - Hosted GraphQL plus popular JS framework

● gqlgen - Go servers generated from schema

● Prisma & Hasura - Pushing GraphQL closer to the database

● Subscriptions

● Fragments

● Unions & Interfaces

Page 39: Nat Welch / SRECon'19 Americas - USENIX...Proprietary + Confidential Most GraphQL endpoints use POST which is not cached by CDNs by default Persisted queries Apollo Automatic Persistent

Proprietary + ConfidentialProprietary + Confidential

Thanks!

DM @icco or come find me in-person if you have questions.

nat.wiki/srecon-graphql