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

Crafting compelling real-time web experiences w...

Rob Crowley
September 21, 2018

Crafting compelling real-time web experiences with GraphQL and React

Users expect real-time data. They want their banking transaction notifications now. Their orders confirmed now. They need prices accurate as of now. They want their user experience to feel—connected. The world has moved to push and users are waiting for the data-driven experiences we create on the web to catch up.

GraphQL is Facebook’s response to this challenge and it is quickly proving itself as an attractive 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 typed, hierarchical and enable clients to retrieve only the data they need.

In addition to the familiar pull based request-response pattern, GraphQL provides a mechanism for clients to subscribe to real-time updates in the form of Subscriptions. Subscriptions are exciting as they represent the core ability we need to satisfy the connected experience that our users demand.

In this talk, we will take a hands-on look at GraphQL and see how it can be used to build real-time APIs that are a joy to use. Additionally, we will explore how to integrate a React client with GraphQL using the ultra flexible, community driven Apollo client. By the end of the session you will understand what is required to craft a compelling real-time user experience with GraphQL, and have the knowledge to deliver on these requirements.

Rob Crowley

September 21, 2018
Tweet

More Decks by Rob Crowley

Other Decks in Programming

Transcript

  1. ▪ GRAPHQL OVERVIEW ▪ THE CASE FOR REALTIME EXPERIENCES ▪

    THE SERVER STORY ▪ A CLIENT PERSPECTIVE ▪ MAKING IT ALL PERFORMANT
  2. HOW CAN EACH CLIENT RETRIEVE EXACTLY THE DATA IT REQUIRES

    IN A SINGLE ROUND TRIP TO THE SERVER?
  3. let queryFilm = (_, {id}, {models}) => { // arbitrary

    code to retrieve film return models.film.get(id); } let filmTitle = film => { // just return property from root film return film.title; }
  4. ▪ IS A QUERY LANGUAGE FOR YOUR API ▪ ALLOWS

    CLIENTS TO CRAFT STRONGLY TYPED QUERIES ▪ FACILITATES RETRIEVING EXACTLY THE DATA YOU REQUIRE ▪ HAS POWERFUL FEATURES SUCH AS INTROSPECTION ▪ IS PRETTY COOL ☺
  5. CUSTOMERS EXPECT THEIR DATA TO BE AVAILABLE IN REALTIME. THIS

    HAS ALREADY HAPPENED AND WE NEED TO CATCH UP .
  6. GREAT WHEN THE DATA REFRESH RATE IS KNOWN OTHERWISE WE

    NEED TO BALANCE FRESHNESS AND CHATTINESS
  7. mutation addReview { addReview(input: { clientMutationId: “MjpGaWxt” content: “Quirky and

    darkly funny”, rating: 9, filmId: 5 }) { clientMutationId } }
  8. ▪ IS SUPPORTED VIA POLLING / SUBSCRIPTIONS / LIVE QUERIES.

    ▪ AFFORDS A CONSISTENT INTERFACE FOR SYNC AND ASYNC QUERIES VIA SUBSCRIPTIONS. ▪ IS VERY POWERFUL WHEN USED APPROPRIATELY.
  9. import { request } from ‘graphql-request’ const query = `{

    film(filmId: “2”) { title description releasedOn } }` request(‘https://api.example.com/graphql’, query) .then(data => console.log(data))
  10. type Actor implements Node { id: ID! actorId: ID! name:

    String appearedIn: ActorFilmsConnection }
  11. type Genre implements Node { id: ID! name: String! description:

    String } type FilmGenresConnection { edges: [FilmGenresEdge] nodes: [Genre] pageInfo: PageInfo! totalCount: Int! } type FilmGenresEdge { cursor: String! node: Genre }
  12. type Review implements Node @defer { id: ID! rating: Rating!

    content: String! @defer film: Film! createdAt: DateTime! }
  13. <Query query={REVIEW_QUERY}> {({ loading, error, data, loadingState }) => {

    if (loading) return <div>Loading...</div>; if (error) return <div>Error :(</div>; return ( <div> {loadingState.review.content ? data.review.content : “Review content pending...”} </div> ); }} </Query>
  14. new ApolloServer({ typeDefs, resolvers, engine: { apiKey: config.apolloEngineKey }, persistedQueries:

    { cache: new RedisCache({ host: config.queryCache.host, port: config.queryCache.port }) }, });
  15. hash:‘4fa973c’ { data: { film { title } } }

    query { film(id: “5”) { title } }
  16. HASHED QUERIES CAN BE SENT AS HTTP GET REQUESTS WITH

    APOLLO CLIENT TO ENABLE CACHING.
  17. type Review implements Node { id: ID! rating: Rating! content:

    String! film: Film! @cacheControl(maxAge: 60) createdAt: DateTime! }
  18. type Review implements Node { id: ID! rating: Rating! content:

    String! @cost(complexity: 2) film: Film! @cacheControl(maxAge: 60) createdAt: DateTime! }