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

GraphQL - A query language to empower your API Consumers (DDD Melbourne 2017)

GraphQL - A query language to empower your API Consumers (DDD Melbourne 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.

Rob Crowley

August 12, 2017
Tweet

More Decks by Rob Crowley

Other Decks in Programming

Transcript

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

    View Slide

  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.

    View Slide

  3. The shift to microservices, cloud native and rich web
    apps have made it challenging to deliver compelling
    API experiences

    View Slide

  4. View Slide

  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

    View Slide

  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

    View Slide

  7. How can we efficiently deliver the data to the client?

    View Slide

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

    View Slide

  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

    View Slide

  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…

    View Slide

  11. Retrieve exactly the data you require in a single
    round trip to the server

    View Slide

  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 }

    View Slide

  13. Source code available at
    https://github.com/robcrowley/graphql-demo

    View Slide

  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

    View Slide

  15. Demo time: Just show me how it works already

    View Slide

  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.

    View Slide

  17. GraphQL Core Concepts

    View Slide

  18. Type System
    Execution
    Engine
    Anatomy of GraphQL
    Query
    Language

    View Slide

  19. “Reliability problems largely occur at module
    boundaries, and most result from inconsistencies in
    both sides expectations”
    - Bertrand Meyer

    View Slide

  20. type Artist {
    id: ID!
    name: String!
    aliases: [String]
    albums: [Album]
    }

    View Slide

  21. let queryArtist = (_, {id}, {dao}) => {
    // arbitrary code to retrieve artist
    return dao.getArtist(id);
    }
    let artistName = artist => {
    return artist.name;
    }

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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
    *

    View Slide

  27. GraphQL Operations
    -Query -> Read ( 1 : 1 )
    -Mutation -> Write ( 1 : 1 )
    -Subscription -> Observe Event ( 1 : 0..* )

    View Slide

  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

    View Slide

  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.

    View Slide

  30. GraphQL is not tied to JavaScript. Server
    implementations exist for many languages.
    http://graphql.org/code

    View Slide

  31. GraphQL is protocol agnostic. So long as the protocol
    supports exchanging character data you’re set.

    View Slide

  32. GraphQL is not about binary data streams

    View Slide

  33. “Every time time you change a version identifier,
    you’re potentially orphaning clients who ‘speak’ that
    language.”
    - Mark Nottingham

    View Slide

  34. In place of versioning prefer an extension model to
    enable graceful evolution of the API contract

    View Slide

  35. The @deprecated directive provides an elegant
    mechanism to facilitate this in GraphQL

    View Slide

  36. GraphQL is not a shortcut to great API design.
    Solid modelling skills are still table stakes.
    (sorry, not sorry)

    View Slide

  37. Think in Graphs*
    Avoid creating fields that should be types

    View Slide

  38. Getting the most out of GraphQL

    View Slide

  39. The schema solves one part of the API documentation
    challenge, it does not solve it completely

    View Slide

  40. graphdoc + schema =
    professional static API documentation

    View Slide

  41. Do not roll your own GraphQL client

    View Slide

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

    View Slide

  43. Naming is difficult and as such is a problem suited to
    API governance

    View Slide

  44. is / can / has prefix for Boolean fields
    plural nouns for collections

    View Slide

  45. Strive for field and type names that mirror the
    language of the business domain

    View Slide

  46. “There are only two hard things in Computer
    Science: cache invalidation and naming things.”
    - Phil Karlton

    View Slide

  47. GraphQL requires a different approach to caching

    View Slide

  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.

    View Slide

  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.

    View Slide

  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.

    View Slide

  51. Server Caching
    - Utilise a dedicated cache layer to
    minimize traffic downstream.
    - DataLoader implementations assist
    with per request batching and
    caching.

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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
    ?

    View Slide

  57. Authentication & Authorization

    View Slide

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

    View Slide

  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

    View Slide

  60. View Slide

  61. View Slide

  62. This approach works well for 1st party systems.
    What about 3rd party systems with delegated access?

    View Slide

  63. Authentication Authentication
    HTTP TCP based protocol
    REST RPC
    Coarse Grained
    Authorization
    GraphQL
    Business Logic
    Authorization

    View Slide

  64. View Slide

  65. View Slide

  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

    View Slide

  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

    View Slide

  68. Real Time APIs
    -Pull
    -Polling
    -Push
    -Live Queries (standard query with infinitely fast polling)
    -Subscriptions (event based)

    View Slide

  69. Subscriptions RFC has been raised
    facebook/graphql#267

    View Slide

  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!

    View Slide

  71. Client
    Request / Response
    GraphQL
    Business Domain

    View Slide

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

    View Slide

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

    View Slide

  74. Example subscription workflow / use case
    User
    Admin
    GraphQL
    Server
    Connect to WS endpoint (ws://api.example.com/subscriptions)

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  78. Low friction development of GraphQL APIs

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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.

    View Slide

  84. GraphQL Faker Demo
    https://github.com/APIs-guru/graphql-faker

    View Slide

  85. Query execution telemetry is vital for identifying
    performance bottlenecks

    View Slide

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

    View Slide

  87. Thank you!

    View Slide

  88. 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/ddd-melbourne-rc-graphql

    View Slide