BETTER APIS WITH
The Future of the Realtime Web
Josh Price @joshprice
GRAPHQL Josh Price @joshprice STEPPING STONES TO FP Language - - PowerPoint PPT Presentation
The Future of the Realtime Web BETTER APIS WITH GRAPHQL Josh Price @joshprice STEPPING STONES TO FP Language (Elixir) Strongly-Typed APIs (GraphQL) GRAPHQL WAS HERE? http://whiteafrican.com/2008/05/12/crossing-the-mapping-chasm/ A
The Future of the Realtime Web
Josh Price @joshprice
STEPPING STONES TO FP
Language (Elixir) Strongly-Typed APIs (GraphQL)
GRAPHQL WAS HERE?
http://whiteafrican.com/2008/05/12/crossing-the-mapping-chasm/COMMON ISSUES WITH REST
A TAXONOMY OF
UNDERFETCHING
▸ N + 1 HTTP request problem ▸ eg. Fetched a Blog Post but not Comments ▸ Must make more requests to fulfil data requirements ▸ For complex views we saw 6-7 requests (usually serial) ▸ Have seen up to 25+ requests in the wild
OVERFETCHING
▸ Client wants a small subset of data from endpoint ▸ But gets everything regardless ▸ The addition of fields to a endpoint bloats payloads ▸ Create more endpoints, but this means more roundtrips ▸ Could create a homepage specific endpoint for each device,
but harder to manage
BIG UPFRONT DESIGN NEEDED
▸ Need to anticipate all current and future clients’ needs ▸ ie Mobile v Web clients ▸ Could have multiple representations/endpoints ▸ Divergence of server code ▸ Keeping everything in sync is hard
HYPERMEDIA ISN’T ALWAYS APPLICABLE
▸ If you control the clients and the server ▸ Less useful for your web or mobile app calling a known API
1000x / sec
▸ Semantics are communicated out of the ▸ A self-describing, well-typed API is an alternative approach
WHAT IS GRAPHQL?
▸ Language for defining schemas, types & queries ▸ It’s a specification for that language (like OpenAPI, Swagger) ▸ Developed by Facebook in 2012 ▸ Used internally to improve mobile app performance ▸ Served 300B+ requests per day (1.6B DAU on mobile) ▸ Open sourced spec in mid 2015
GENERALISED
GRAPHQL APIS ARE
GRAPHQL APIS ARE
BETTER
SELF DESCRIBING AND
CONSUMER DRIVEN CONTRACTS
EXPOSE YOUR DOMAIN MODEL VIA
QUERIES AND RESPONSES ARE
STRONGLY TYPED APIS
TYPES IN YOUR SCHEMA ==
BUILT-IN FIELD DEPRECATION MEANS
YOU DO NOT NEED A
THIS IS NOT YOUR TYPICAL
NOT ONLY FOR JAVASCRIPT
NOT DEPENDENT ON
DOES NOT REPLACE REST
IT’S EASIER TO WORK WITH BUT
POTENTIALLY
LET’S LEARN SOME
SCHEMAS, TYPES AND SCALARS
type Meetup { title: String! date: Date description: String url: URL! talks: [Talk!]! } type Talk { title: String! description: Markdown presenter: Person! } schema { query: Query mutation: Mutation }GraphQL SDL
SCHEMAS, TYPES AND SCALARS
type Meetup { title: String! date: Date description: String url: URL! talks: [Talk!]! } type Talk { title: String! description: String presenter: Person! } schema { query: Query mutation: Mutation } @desc "A meetup”GraphQL SDL Elixir with Absinthe
RESOLVER FUNCTIONS FETCH YOUR DATA
▸ Resolver functions fetch (or update) data ▸ Called when query fields are matched against schema fields ▸ Return data or an error ▸ Can take arguments specified in schema ▸ Can take a context in from the query (ie current user for
authentication and authorisation)
RESOLVER FUNCTIONS (ELIXIR EXAMPLE)
defmodule GraphqlSydney.GraphQL.Schema do use Absinthe.Schema alias GraphqlSydney.Events import_types Absinthe.Type.Custom query do @desc "Get the next meetup" field :next_meetup, type: :meetup do resolve fn _, _ -> {:ok, Events.next_meetup} end end @desc "Get the previous meetups" field :previous_meetups, type: list_of(:meetup) do resolve fn _, _ -> {:ok, Events.past_meetups} end end end endQUERY PROCESSING PIPELINE
▸ Client send Query documents as Strings ▸ Server Parses into AST ▸ Validation of AST ▸ Query fields matched against Schema ▸ Matching resolver functions executed ▸ Data (and errors) returned to client as a Map
SIMPLE QUERY LIFECYCLE
Query (String) Response (Map) Data Fetching Run Resolver FunctionsQUERY: FETCH NEXT MEETUP
QUERY: AUTOCOMPLETE / AUTOCORRECTION
QUERY: FETCH NEXT MEETUP’S TALKS
QUERY: INLINE DOCUMENTATION
QUERY: MEETUP WITH TALKS AND PRESENTERS
STEP 1: PICK A SERVER IMPLEMENTATION
▸ JavaScript reference implementation ▸ Apollo Server Tools ▸ Java / Scala (Sangria) ▸ .NET / F# ▸ Ruby / Python / PHP ▸ Elixir / Erlang ▸ Go / Rust / Haskell
STEP 2: WRITE YOUR SCHEMA
▸ Figure out your domain types ▸ Write top level queries for reads ▸ Add mutations for writes ▸ Subscriptions for reactive data changes ▸ Don’t forget field descriptions!
STEP 3: CHOOSE A CLIENT
▸ Relay Modern ▸ Declare data requirements of UI component as query fragments ▸ Sends a single query ▸ Render collects query fragments in the render tree ▸ Caches objects by unique ID ▸ Added graph convention of nodes and edges ▸ Pagination metadata, etc ▸ Not actually part of the spec and can be confusing
STEP 3: CHOOSE A CLIENT
▸ Apollo 2.0 ▸ Bit simpler than Relay, no graph conventions ▸ Hand rolled queries for each view ▸ Handles client side caching ▸ Probably easiest to start here ▸ Also has native iOS and Android client libs
STEP 4: PROFIT
▸ Start with read only first ▸ Shim existing REST APIs ▸ Frontend and Backend need to be on board ▸ Easy to experiment ▸ Try it out on new non-critical path projects
COMPLEX AND PATHOLOGICAL QUERIES
▸ Denial of Service possible for slow queries ▸ Be careful with exposing sorting, filtering and aggregation ▸ ie Don’t expose a sort field without an index ▸ Limit query depth and/or complexity ▸ Not all implementations have this though ▸ Instrumentation can alleviate this
AVOID “STRINGLY TYPING”
▸ It’s very easy overuse plain String types ▸ You lose information: makes mocking harder ▸ There are no type aliases in the spec (yet) ▸ Can write your own custom Scalars (impl specific) ▸ Fine-grained “Micro-types” are useful ▸ ie URL, Email, Markdown, Name, Money, etc
NO HTTP CACHING
▸ Can send queries by GET ▸ POST is preferred ▸ Can’t use standard HTTP caching ▸ Varnish, Squid, etc ▸ Can cache elsewhere however ▸ Client, Resolvers, Data Store, etc
QUERY EXECUTION TRACING
INTEGRATED CACHE MANAGEMENT
ERROR TRACKING
SCHEMA ANALYSIS
SCHEMA COMPOSITION
SCHEMA STITCHING GRAFT
SCHEMA COMPOSITION TOOLS
▸ Apollo Schema Stitching ▸ https://dev-blog.apollodata.com/graphql-schema-
stitching-8af23354ac37
▸ Gramps the IBM microservice API composition framework ▸ https://github.com/gramps-graphql/gramps ▸ GraphQL Weaver ▸ https://github.com/AEB-labs/graphql-weaver
REALTIME APIS WITH SUBSCRIPTIONS
HTTP/2 PUSH AND THE RISE OF
HAS GRAPHQL CROSSED THE CHASM?
GRAPHQL IS HERE
http://whiteafrican.com/2008/05/12/crossing-the-mapping-chasm/RESOURCES
▸ http://graphql.org/ ▸ https://github.com/chentsulin/awesome-graphql ▸ https://www.apollographql.com/ ▸ https://facebook.github.io/relay/ ▸ GraphQL Summit Videos ▸ https://www.youtube.com/playlist?
list=PLpi1lPB6opQywks7yYYs5jJAIRI3faRTm