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

Practical GraphQL with speaker notes

Practical GraphQL with speaker notes

Alexander Savin

January 05, 2016
Tweet

More Decks by Alexander Savin

Other Decks in Programming

Transcript

  1. ABOUT ME Alexander Savin Web developer @ 
 Red Badger

    Skydiver Originally from Russia, lived most of my life in Finland, and moved to UK 2 years ago. Brighton was my first place to visit after landing in London.
  2. REACT LONDON MEETUP > 2000 members Started in summer 2014

    with a small meetup at RB HQ By December 2014 we’ve noticed that we need more space for this meetup.
  3. GRAPHQL GraphQL as a conversation opener. A bit misleading title

    for this talk - we’re going to touch on Relay, REST and even React Native. Keep it practical. How many of you are using Node, React, GraphQL?
  4. FRONT END APP SERVICE A SERVICE C SERVICE B SERVICE

    D Service A implements an alternative version of REST Service B implements an endpoint that tries to drive the UI Service C haven't implemented anything yet Service D implemented a service which is only available on a specific internal WIFI network. When you connect to it, none of the other endpoints are available. You mission, should you choose to accept it, is to consume all of the mentioned endpoints while providing great user experience.
  5. FACEBOOK CASE Facebook started as a monolithic web app. Native

    mobile client v1 was limited in features. Mobile app v2 was web app based, equal in features, bad in performance Mobile app v3 was again 100% native and full of features, but that required change on how data is server from backend. Gravity shift from a web app to data delivery to a multiple clients. Inability to make such adjustments can kill companies.
  6. GRAPHQL SERVER So what is it and how it works?

    You would have a server, and a client
  7. { user { name } } { “user”: { “name”:

    “Alex Savin” } } GraphQL JSON
  8. mutation AddUser { createUser(input: {first_name: "Alex" }) { } }

    When implementing mutation you can split the task into 2 parts. First define mutation name and arguments
  9. mutation AddUser { createUser(input: {first_name: "Alex" }) { changedUser {

    first_name } } } Secondly, decide what kind of query we want to be returned after mutation is done.
  10. { user(id: 123456) { …UserDetails } } fragment UserDetails on

    User { first_name last_name email twitter town homepage }
  11. type User { name: String id: String! } TYPE ROOT

    QUERY type Query { user(id: String!): User }
  12. If you never used GraphiQL before, right now you should

    be like.. hmm. The way GraphiQL works is INTROSPECTION Introspection can be used also for generating documentation. Tool for exploring schema and building tools Way of selling GraphQL to anyone (Introspection - the way GraphiQL works, and other tools could too)
  13. { __schema { types { fields { name description }

    } } } Introspection can be used for generating documentation
  14. DATA SHAPE EQUALITY What you request is what you get

    WYRIWYG No more data massaging - client request data in a shape it prepared to consume
  15. SINGLE REQUEST / RESPONSE FOR A CLIENT It takes 2

    seconds for a single http request on mobile 2G network. And it can fail. HTTP requests are still costly, especially on mobile.
  16. { "created_at": "2015-08-30T00:50:25.000+00:00", "genres": [], "id": "e66637db-13f9-4056-abef-f731f8b1a3c7", "like_count": 3, "liked_count":

    3, "name": "Excuse me while I kiss these frets", "owner": { "avatar_url": "https://secure.gravatar.com/avatar/ 4ede0ad35bb796ea8f78861acc4372ca?s=300", "bio": null, "id": "b06e671a-b169-45e6-a645-74c31abca910", "login": "playlistrock", "name": "Playlist Rock", RESTful responses tend to grow to accomodate different clients and use cases Overfetching Data massaging on clients Specifications and documentations is usually awful for REST endpoints
  17. { "created_at": "2015-08-30T00:50:25.000+00:00", "genres": [], "id": "e66637db-13f9-4056-abef-f731f8b1a3c7", "like_count": 3, "liked_count":

    3, "name": "Excuse me while I kiss these frets", "owner": { "avatar_url": "https://secure.gravatar.com/avatar/4ede0ad35bb796ea8f78861acc4372ca?s=300", "bio": null, "id": "b06e671a-b169-45e6-a645-74c31abca910", "login": "playlistrock", "name": "Playlist Rock", "site_admin": false }, "published": false, "saved_count": 3, "tags": [ { "name": "Jimi Hendrix" }, { "name": "Jimmy Page" }, { "name": "Eric Clapton" }, … https://blog.jacobwgillespie.com/from-rest-to-graphql-b4e95e94c26b RESTful responses tend to grow to accommodate different clients and use cases Overfetching Data massaging on clients
  18. GRAPHQL IS A SPEC http://facebook.github.io/graphql/ GraphQL is a language. There

    are multiple implementations, including reference JS one by Facebook, .NET, Ruby, Scala. GraphQL server can be implemented using any language. You can use any database with that implementation. Clients can use any protocol to relay data.
  19. EXPRESS GRAPHQL DEMO In addition to language spec, FB provided

    reference implementation of it in JavaScript, as well as Node middleware for easy integration. Let’s see this in action. We will also now venture on the server side and see how things are working there - in particular how request being received and resolved into response. We cheated a bit with reindex.io in the beginning, which takes this complexity away. Express middleware uses RESTful GET / POST requests.
  20. ASYNC RESOLVE {} Resolve can be asynchronous. This is useful

    when you’re querying multiple RESTful endpoints. Compose a list of promises. Resolve all promises. Compose a list of errors / successes. Compose a JSON response.
  21. async resolve(obj, {...}) { const endpoints = [ { endpoint:

    'voiceNumber', data: contactNumber }, { endpoint: 'smsNumber', data: contactNumber }, { endpoint: 'email', data: email }, ]; const processEndpoint = async ({endpoint, data}) => { try { return await contactService[endpoint](data); } catch (error) { return error; } }; const processes = [ for (process of endpoints)
  22. const processes = [ for (process of endpoints) processEndpoint(process) ];

    const responses = await* processes; const errors = responses.filter(response => response instanceof Error); if (errors.length) { throw errors; } return { accessToken, refreshToken, }; }
  23. RELAY Relay is a framework connecting React application with the

    GraphQL server EXTENDING SELF-CONTAINER COMPONENT, DEMO
  24. Tried many times to different degree of success Facebook approaches

    this by providing great tools for developing things from scratch There are some ways to success
  25. OPTIMISTIC UPDATES ERROR HANDLING OPTIMAL DATA FETCHING Optimistic updates are

    generally tricky to implement. Relay handles this via central app state. There is also temporary state where all mutations are initially live. If server response is successful, temporary state is merged with the central state. Once data requirements are declared, Relay is smart enough to only request data that is not cached yet. It will do caching too. Expect support for offline mode and flaky networks soon. React was easy to start using in 5 min, Relay takes some time to get used to. Mutations are notoriously famous fir their complexity. Debugging Relay should become easier soon once new React dev tools are released - for now it is inspecting GET / POST requests in Chrome devtools.
  26. COMPONENTS DECLARE WHAT DATA THEY NEED View components would be

    wrapped into Relay container component, which would declare what data is needed for this component. Live demo.
  27. Relay with React Native Allows code re-usability across iOS and

    Android 87% in case of this app You will have to re-write UI components, but Relay logic, mutations and queries can be re-used across platforms - web, iOS and Android Learn once, write everywhere
  28. FRONT END APP SERVICE A SERVICE C SERVICE B SERVICE

    D GRAPHQL SERVER Contain data massaging logic in GraphQL server Handle all RESTful service orchestration in a single place Allow clients to evolve nicely and make flexible requests
  29. FRONT END APP SERVICE A SERVICE C SERVICE B SERVICE

    D GRAPHQL SERVER IOS ANDROID TODO: versions of the apps feeding from the same GraphQL server Give yourself space to evolve Also allows you easily mock external services You just mock responses in resolve() And easy to test Can develop in isolation
  30. FRONT END APP SERVICE A SERVICE C SERVICE B SERVICE

    D GRAPHQL SERVER IOS ANDROID FRONT END APP V2 IOS V2 ANDROID V2 TODO: versions of the apps feeding from the same GraphQL server Give yourself space to evolve Also allows you easily mock external services You just mock responses in resolve() And easy to test Can develop in isolation
  31. FRONT END APP GRAPHQL SERVER IOS ANDROID FRONT END APP

    V2 IOS V2 ANDROID V2 TODO: versions of the apps feeding from the same GraphQL server Give yourself space to evolve Also allows you easily mock external services You just mock responses in resolve() And easy to test Can develop in isolation
  32. REFERENCES • http://red-badger.com/blog/2015/08/28/give-it-5-days-facebook-relay-and-graphql/ • http://red-badger.com/blog/2015/07/09/graphql-and-the-open-movie-database-from- introspection-to-inception/ • https://blog.jacobwgillespie.com/from-rest-to-graphql-b4e95e94c26b • https://www.youtube.com/watch?v=Ed6oJXKt3-M

    - Nick Schrock on GraphQL • http://graphql.org/ • https://www.reindex.io/ • http://radiobadger.com/posts/2015-11-05-episode-26.html Shameless but relevant plug - when Relay team was in London I went to Facebook to make an interview, which is now available as Radio Badger podcast episode.