Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQL - A query language to empower your API consumers (NDC Sydney 2017)

GraphQL - A query language to empower your API consumers (NDC Sydney 2017)

The shift to microservices, cloud native and rich web apps have made it challenging to deliver compelling API experiences. REST, as specified in Roy Fielding’s seminal dissertation, has become the architectural pattern of choice for APIs and when applied correctly allows for clients and servers to evolve in a loosely coupled manner. There are areas however where REST can deliver less than ideal client experiences. Often many HTTP requests are required to render a single view.
While this may be a minor concern for a web app running on a WAN with low latency and high bandwidth, it can yield poor client experiences for mobile clients in particular. GraphQL is Facebook’s response to this challenge and it is quickly proving itself as an exciting alternative to RESTful APIs for a wide range of contexts. GraphQL is a query language that provides a clean and simple syntax for consumers to interrogate your APIs. These queries are strongly types, hierarchical and enable clients to retrieve only the data they need.

In this session, we will take a hands-on look at GraphQL and see how it can be used to build APIs that are a joy to use.

3353b76e1480888ea7a482ebaa883dcb?s=128

Rob Crowley

August 18, 2017
Tweet

Transcript

  1. @robdcrowley | robdcrowley GraphQL A query language to empower your

    API consumers
  2. Goals for the session -Explore the motivation behind GraphQL and

    the category of problems it helps to solve. -Take a tour of GraphQL’s features and see it in action. -Investigate how to effectively leverage GraphQL in your delivery process. -Most of all sufficiently motivate you to continue to learn GraphQL after leaving this conference.
  3. The shift to microservices, cloud native and rich web apps

    have made it challenging to deliver compelling API experiences
  4. None
  5. Image Service Cross Sell Service Product Service Product Service Product

    Service Review Service Price Service Inventory Service Promotions Service Other Sellers Service Price Service Image Service Inventory Service Order Service Image Service Price Service
  6. Cross Sell Component Header Component Product Image Component Product Review

    Component Product Price Component Product Inventory Component Product Purchase Component Alternate Sellers Component Product Details Component Offers Component Product Header Component
  7. How can we efficiently deliver the data to the client?

  8. A naïve approach Microservice Microservice Microservice Microservice Component Potentially high

    latency connection Component Component Component
  9. Leveraging an API Gateway to reduce latency Microservice Microservice Microservice

    Microservice API Gateway Wait, we support more than one customer experience channel. How to handle these? Component Component Component Component
  10. Introducing Backends for Frontends (BFFs) Microservice Microservice Microservice Microservice Mobile

    BFF Desktop BFF Wearables BFF What about the different data requirements between versions? V4, V5… On page reload V1, V2…
  11. Retrieve exactly the data you require in a single round

    trip to the server
  12. GraphQL as the translation layer Microservice Relational DB Graph DB

    Web Service GraphQL API Retrieve exactly the data every version of each channel experience requires in one round trip. optimised { data }
  13. Source code available at https://github.com/robcrowley/graphql-demo

  14. Our Example Domain Album Artist Label User Album Review compose

    submit favourite released on refers to 1 * * 1 1 * * 1 1 * artistId: int name: string albumId: int title: string labelId: int name: string founded: int userId: int name: string reviewId: int albumId: int review: string rating: int
  15. Demo time: Just show me how it works already

  16. Hey, just what are you trying to pull here!? Couldn’t

    we already do this with REST? Absolutely, but GraphQL makes it trivial and ensures a consistent interface.
  17. GraphQL Core Concepts

  18. Type System Execution Engine Anatomy of GraphQL Query Language

  19. “Reliability problems largely occur at module boundaries, and most result

    from inconsistencies in both sides expectations” - Bertrand Meyer
  20. type Artist { id: ID! name: String! aliases: [String] albums:

    [Album] }
  21. let queryArtist = (_, {id}, {dao}) => { // arbitrary

    code to retrieve artist return dao.getArtist(id); } let artistName = artist => { return artist.name; }
  22. root query { artist(id: “5”) { name albums { title

    label { name } } } } Label Producer Album User Artist Review
  23. root query { artist(id: “5”) { name albums { }

    } } Label Producer Album User Artist Review
  24. root Label Producer Album User Artist Review query { artist(id:

    “5”) { name albums { title label { } } } }
  25. root Label Producer Album User Artist Review query { artist(id:

    “5”) { name albums { title label { name } } } }
  26. Capabilities exposed as schema Requirements expressed as query GraphQL focusses

    on accessing data exposed by the graph This is a fundamental difference to REST which is concerned with modelling resources and state transitions. Clients Single /graphql endpoint *
  27. GraphQL Operations -Query -> Read ( 1 : 1 )

    -Mutation -> Write ( 1 : 1 ) -Subscription -> Observe Event ( 1 : 0..* )
  28. -The second killer feature of GraphQL -Enables ‘reflection’ type queries

    on fields, types and schema -Extremely powerful for tooling support - Autocomplete (as seen in Graphiql) - Code generation - Documentation Introspection
  29. Efficiency -Avoid overfetching and underfetching (particularly across the slow portion

    of the network to the client). -Reduced data handling complexity in the client. -Simpler extension model for backend API developers.
  30. GraphQL is not tied to JavaScript. Server implementations exist for

    many languages. http://graphql.org/code
  31. GraphQL is protocol agnostic. So long as the protocol supports

    exchanging character data you’re set.
  32. GraphQL is not about binary data streams

  33. “Every time time you change a version identifier, you’re potentially

    orphaning clients who ‘speak’ that language.” - Mark Nottingham
  34. In place of versioning prefer an extension model to enable

    graceful evolution of the API contract
  35. The @deprecated directive provides an elegant mechanism to facilitate this

    in GraphQL
  36. GraphQL is not a shortcut to great API design. Solid

    modelling skills are still table stakes. (sorry, not sorry)
  37. Think in Graphs* Avoid creating fields that should be types

    <zen> </zen>
  38. Getting the most out of GraphQL

  39. The schema solves one part of the API documentation challenge,

    it does not solve it completely
  40. graphdoc + schema = professional static API documentation

  41. Do not roll your own GraphQL client

  42. Decide whether you will support Relay early https://facebook.github.io/relay

  43. Naming is difficult and as such is a problem suited

    to API governance
  44. is / can / has prefix for Boolean fields plural

    nouns for collections
  45. Strive for field and type names that mirror the language

    of the business domain
  46. “There are only two hard things in Computer Science: cache

    invalidation and naming things.” - Phil Karlton
  47. GraphQL requires a different approach to caching

  48. Caching Approaches for RESTful APIs Client Side Caching Server Side

    Caching HTTP offers rich caching functionality via caching headers: Cache-Control, ETag, Expires, Pragma & Vary.
  49. Caching Approaches for RESTful APIs Client Side Caching Server Side

    Caching Intermediate Caching Proxy HTTP offers rich caching functionality via caching headers: Cache-Control, ETag, Expires, Pragma & Vary.
  50. Caching Approaches for GraphQL APIs Client Side Caching Server Side

    Caching Intermediate Caching Proxy GraphQL does not play nice with the rest of the web, as it treats HTTP as a dump pipe. As such we need to rely on server and client caching.
  51. Server Caching - Utilise a dedicated cache layer to minimize

    traffic downstream. - DataLoader implementations assist with per request batching and caching.
  52. Client Caching - GraphQL clients such as Apollo or Relay

    help massively in this regard. - Hierarchical responses are flattened to create normalized caches where each record is stored exactly once. - Clients can leverage this cache to generate network efficient queries. query: { album (id: “1”): { name: “Endtroducing…" artist: { name: “DJ Shadow" } } } Map { 1: Map { name: “Endtroducing…”, author: Link(2), }, 2: Map { name: ‘DJ Shadow' }, }; Hierarchical Normalized
  53. Inter API Communication - Inter API calls are easily supported

    in REST APIs based of the media type semantics. - In fact, Hypermedia is the under- pinning architectural style of the web. GET /artistsapi/artist/1 HTTP/1.1 ContentType: application/vnd.hal+json { “_links”: { “events” : { “href”: “/eventsapi/performers/8”, “type” : “application/vnd.siren+json” } /* … other fields … */ } Events API Artists API
  54. Inter API Communication - Inter API calls are easily supported

    in REST APIs based of the media type semantics. - In fact, Hypermedia is the under- pinning architectural style of the web. GET /eventsapi/events/8 HTTP/1.1 ContentType: application/vnd.siren+json { "class": [ “event" ], "properties": { “startDate": “2017-09-18T15:00:00+10:00”, “endDate: “2017-08-18T16:00:00+10:00”, “availableTicketCount": 42 }, /* … other fields … */ } Events API Artists API
  55. { “data”: { “artist” : { “events”: [ { “url”:

    “/eventsapi/performers/8” } ] } } } Inter API Communication - There is no easy way to federate calls across GraphQL schemas. - Ideally model these as additional nodes and edges in the same GraphQL schema. - Failing this we must defer to ‘out of band’ sources such as API documentation. POST /graphql HTTP/1.1 { artist { events { url } } } Events API GraphQL API
  56. { “data”: { “artist” : { “events”: [ { “url”:

    “/eventsapi/performers/8” } ] } } } Inter API Communication - There is no easy way to federate calls across GraphQL schemas. - Ideally model these as additional nodes and edges in the same GraphQL schema. - Failing this we must defer to ‘out of band’ sources such as API documentation. POST /graphql HTTP/1.1 { artist { events { url } } } Events API GraphQL API ?
  57. Authentication & Authorization

  58. GraphQL REST RPC Business Logic Authentication Authentication Authorization HTTP TCP

    based protocol
  59. As a User, I want to be the only one

    permitted to see my personal details So that my right to privacy is respected
  60. None
  61. None
  62. This approach works well for 1st party systems. What about

    3rd party systems with delegated access?
  63. Authentication Authentication HTTP TCP based protocol REST RPC Coarse Grained

    Authorization GraphQL Business Logic Authorization
  64. None
  65. None
  66. Image by toffehoff via https://www.flickr.com/photos/toffehoff/244870161/ So far we have been

    pulling data what if we could we enable the pushing of data
  67. As a User, I want to be notified when my

    favourite artists release albums So that I can keep to up to date with the music that I love
  68. Real Time APIs -Pull -Polling -Push -Live Queries (standard query

    with infinitely fast polling) -Subscriptions (event based)
  69. Subscriptions RFC has been raised facebook/graphql#267

  70. Event Based Subscriptions -Concept: Server pushes message to client when

    ‘something’ occurs -Read only -Expressed using GraphQL syntax -Not a replacement for GraphQL queries!
  71. Client Request / Response GraphQL Business Domain

  72. Subscriptions Client Request / Response GraphQL Events Bi-directional Transport Business

    Domain
  73. Subscriptions Client Request / Response GraphQL Events Bi-directional Transport Business

    Domain Subscription Event
  74. Example subscription workflow / use case User Admin GraphQL Server

    Connect to WS endpoint (ws://api.example.com/subscriptions)
  75. Example subscription workflow / use case Subscribe to advertised event

    (http://api.example.com/graphql) subscription onAlbumAdded { albumAdded(userId: “1”) { album { title } artist { name } } } User Admin GraphQL Server Web socket connection open and waiting for published events
  76. Example subscription workflow / use case User Admin mutation addAlbum

    { addAlbum(album: {title: "Cold Water Music", artistId: 1, labelId: 1 }) { artist { id name } } } Admin user adds new album using addAlbum mutation GraphQL Server Web socket connection open and waiting for published events
  77. Album added event document pushed to client Example subscription workflow

    / use case User Admin { albumAdded: { album: { title: “Cold Water Music” } artist: { name: “Aim” } } } GraphQL Server
  78. Low friction development of GraphQL APIs

  79. GraphQL Dev Workflow - Front end and back end teams

    agree on schema. - UI is developed using mocked data based on schema - API is built out with any changes being communicated to front end team - Integrate front and back ends - Ship - Repeat Schema App Api Product
  80. GraphQL Dev Workflow - Front end and back end teams

    agree on schema. - UI is developed using mocked data based on schema - API is built out with any changes being communicated to front end team - Integrate front and back ends - Ship - Repeat Schema App Api Product
  81. GraphQL Dev Workflow - Front end and back end teams

    agree on schema. - UI is developed using mocked data based on schema - API is built out with any changes being communicated to front end team - Integrate front and back ends - Ship - Repeat Schema App Api Product
  82. GraphQL Dev Workflow - Front end and back end teams

    agree on schema. - UI is developed using mocked data based on schema - API is built out with any changes being communicated to front end team - Integrate front and back ends - Ship - Repeat Schema App Api Product
  83. { real { data } fake { data } }

    { real { data } } { real { data: “resolved” } } { real { data: “resolved” } fake { data: “stubbed” } } IDL application/graphql application/json GraphQL Faker facilitates low friction experimentation when modelling schema. It’s quicker to change IDL than the API.
  84. GraphQL Faker Demo https://github.com/APIs-guru/graphql-faker

  85. Query execution telemetry is vital for identifying performance bottlenecks

  86. Build support for a phased release approach for API changes

  87. Takeaways

  88. Thank you!

  89. Resources - Official Docs: http://graphql.org - Specification: https://github.com/facebook/graphql - Reference:

    https://github.com/graphql/graphql-js - Community: http://graphql.org/community - Awesome List: https://github.com/chentsulin/awesome-graphql - Humble Additions - Code: https://github.com/robcrowley/graphql-demo - Slides: https://bit.ly/ndcsydney-graphql