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 TAXONOMY OF COMMON ISSUES WITH REST
PERFORMANCE
UNDERFETCHING
COMMON ISSUES WITH REST 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
COMMON ISSUES WITH REST 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
COMMON ISSUES WITH REST 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?
COMMON ISSUES WITH REST 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
GRAPHQL
GRAPHQL HISTORY 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 DATA FETCHING
GRAPHQL APIS ARE EASIER TO BUILD
GRAPHQL APIS ARE EASIER TO CONSUME
BETTER PERFORMANCE
SELF DESCRIBING AND SELF DOCUMENTING
EXPOSE YOUR DOMAIN MODEL VIA CONSUMER DRIVEN CONTRACTS
QUERIES AND RESPONSES ARE ISOMORPHIC
TYPES IN YOUR SCHEMA == STRONGLY TYPED APIS
BUILT-IN FIELD DEPRECATION MEANS EASIER EVOLUTION
MYTHS & MISCONCEPTIONS
YOU DO NOT NEED A GRAPH DATABASE
THIS IS NOT YOUR TYPICAL QUERY LANGUAGE
NOT ONLY FOR JAVASCRIPT LANGUAGE AGNOSTIC
NOT DEPENDENT ON HTTP OR JSON
IT’S EASIER TO WORK WITH BUT DOES NOT REPLACE REST
POTENTIALLY MAKES REST EASIER
LET’S LEARN SOME GRAPHQL CONCEPTS
SCHEMAS, TYPES AND SCALARS GraphQL SDL 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 }
SCHEMAS, TYPES AND SCALARS GraphQL SDL Elixir with Absinthe @desc "A meetup” type Meetup { object :meetup do title: String ! @desc "The title of the meetup" date: Date field :title , non_null( :string) description: String url: URL ! @desc "The date of the meetup" talks: [ Talk !]! field :date , :date } @desc "The description of the meetup" type Talk { field :description , :string title: String ! description: String @desc "The Meetup.com url" presenter: Person ! field :url , :string } @desc "The talks at the meetup" schema { field :talks , list_of( :talk ) query: Query end mutation: Mutation }
GRAPHQL CONCEPTS 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)
GRAPHQL CONCEPTS 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 end
GRAPHQL CONCEPTS QUERY 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 Run Resolver Functions Data Fetching DB Query (String) 1 2 CLIENT 4 Response (Map) 3 CMS
LET’S SEE IT IN ACTION!
QUERY: FETCH NEXT MEETUP
QUERY: AUTOCOMPLETE / AUTOCORRECTION
QUERY: FETCH NEXT MEETUP’S TALKS
QUERY: INLINE DOCUMENTATION
QUERY: MEETUP WITH TALKS AND PRESENTERS
GETTING STARTED
HOW TO GET STARTED WITH GRAPHQL 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
HOW TO GET STARTED WITH GRAPHQL 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!
HOW TO GET STARTED WITH GRAPHQL 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
HOW TO GET STARTED WITH GRAPHQL 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
HOW TO GET STARTED WITH GRAPHQL 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
THINGS TO WATCH OUT FOR
THINGS TO WATCH OUT FOR 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
THINGS TO WATCH OUT FOR 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
THINGS TO WATCH OUT FOR 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
RICH TOOLING ECOSYSTEM
EXPORATION & VISUALISATION
GRAPHQL SERVER ANALYTICS
QUERY EXECUTION TRACING
INTEGRATED CACHE MANAGEMENT
ERROR TRACKING
SCHEMA ANALYSIS
SCHEMA STITCHING AND COMPOSITION
SCHEMA COMPOSITION
SCHEMA STITCHING GRAFT
TOOL ECOSYSTEM 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
API MOCKING
GRAPHQL STACKS
CMS BACKENDS
GRAPHQL BACKENDS AS A SERVICE
REALTIME APIS WITH SUBSCRIPTIONS
HTTP/2 PUSH AND THE RISE OF REACTIVE BACKENDS
HAS GRAPHQL CROSSED THE CHASM?
GRAPHQL IS HERE http://whiteafrican.com/2008/05/12/crossing-the-mapping-chasm/
NEXT STEPS 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
Recommend
More recommend