Slide 1

Slide 1 text

GraphQL on Rails exAspArk Evgeny Li

Slide 2

Slide 2 text

Hello RailsConf!

Slide 3

Slide 3 text

Hello RailsConf! https://giphy.com/gifs/car-snow-gx1YKF48aO0ms

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

• Everything you need to know about GraphQL • Simple application with Ruby on Rails + React + Webpacker • GraphQL schema definition on the server-side • Consuming GraphQL API, automatic code generation, integration • Extra: error handling, authorization, monitoring, N+1 queries What are we doing today?

Slide 6

Slide 6 text

Who is using GraphQL? http://graphql.org/users/

Slide 7

Slide 7 text

But what is GraphQL?

Slide 8

Slide 8 text

Query Language for APIs http://graphql.org/

Slide 9

Slide 9 text

Why graph? Query

Slide 10

Slide 10 text

Why graph? Query Post

Slide 11

Slide 11 text

Why graph? Query Post Title

Slide 12

Slide 12 text

Why graph? Query Post Title Content

Slide 13

Slide 13 text

Why graph? User Query Post Title Content

Slide 14

Slide 14 text

Why graph? User Query Name Post Title Content

Slide 15

Slide 15 text

Why graph? User Query Name Post Title Content Comment

Slide 16

Slide 16 text

Why graph? User Query Name Post Title Content Comment

Slide 17

Slide 17 text

Why graph? User Query Name Post Title Content Comment Text

Slide 18

Slide 18 text

Why graph? User Query Name Post Title Content Comment Text Mutation Subscription

Slide 19

Slide 19 text

GraphQL specification http://facebook.github.io/graphql/October2016/

Slide 20

Slide 20 text

Server describes what data is available User Query Name Post Title Content Comment Text Mutation Subscription

Slide 21

Slide 21 text

Clients ask what data they need User Query Name Post Title Content Comment Text Mutation Subscription

Slide 22

Slide 22 text

TreeQL

Slide 23

Slide 23 text

Request Response Almost the same shape

Slide 24

Slide 24 text

• What is GraphQL and why a graph, GraphQL specification • New blog application with Rails v5.2 • What is Webpack, Webpacker vs Sprockets • One-way data flow, React vs Turbolinks • Static HTML template Part 1: Bootstrapping simple application

Slide 25

Slide 25 text

Let’s create a new Rails app https://yarnpkg.com/lang/en/docs/install/

Slide 26

Slide 26 text

What is Webpack? https://webpack.js.org/

Slide 27

Slide 27 text

• Hot Module Replacement – faster build time without a full reload • Tons of loaders – ES6, CSS post-processors, linters • Tree shaking – exclude unused code • Code splitting – separate static and dynamic parts of your code • Compression, source-maps, minification • WebAssembly support Webpack

Slide 28

Slide 28 text

Webpack vs Sprockets https://media.giphy.com/media/6Z3D5t31ZdoNW/giphy.gif

Slide 29

Slide 29 text

• Smooth integration with Webpack – The Rails Way™ • React, Angular, Elm and Vue support out-of-the-box • Rails view helpers Webpacker https://github.com/rails/webpacker

Slide 30

Slide 30 text

Running Webpacker https://github.com/rails/webpacker/issues/1295

Slide 31

Slide 31 text

Trying to run Webpacker again https://github.com/rails/webpacker/issues/1303

Slide 32

Slide 32 text

Trying to run Webpacker again https://github.com/rails/webpacker/issues/1303

Slide 33

Slide 33 text

And again

Slide 34

Slide 34 text

And again Leaky abstractions

Slide 35

Slide 35 text

Webpacker Once you become familiar with Webpack, you probably don’t need to use Webpacker – an extra dependency, doesn’t support the latest versions. https://medium.com/webpack/webpack-4-released-today-6cdb994702d4

Slide 36

Slide 36 text

Clone the repo https://github.com/exAspArk/graphql-on-rails

Slide 37

Slide 37 text

Run Rails

Slide 38

Slide 38 text

Render layout

Slide 39

Slide 39 text

Render layout

Slide 40

Slide 40 text

Render layout

Slide 41

Slide 41 text

What is React? ____ https://reactjs.org/ • JavaScript library for building user interfaces • Update and render just the right components when your data changes • Declarative views make your code more predictable and easier to debug • Encapsulated components that manage their own state • Learn once, write anywhere (React Native), not opinionated • Great ecosystem, a lot of tools and libraries

Slide 42

Slide 42 text

One-way data flow Browser DOM implementations are generally really slow. One-way data-binding is the process of completely regenerating the HTML whenever the state from a single source changes.

Slide 43

Slide 43 text

Two-way data flow value = ‘Input’ Input

Slide 44

Slide 44 text

value = ‘Input’ Input value = ‘Input123’ Input123 Two-way data flow

Slide 45

Slide 45 text

Two-way data flow value = ‘Input’ Input value = ‘Input123’ Input123 value = ‘Input321’ Input321

Slide 46

Slide 46 text

The jQuery way™ value = ‘Input’ Input value = ‘Input123’ Input123 value = ‘Input321’ Input321 Source of truth Source of truth

Slide 47

Slide 47 text

One-way data flow value = ‘Input’ Input value = ‘Input123’ Input123 Input321 function(‘Input321’) value = ‘Input321’ Input321 Single source of truth

Slide 48

Slide 48 text

Why one-way flow is simpler? Server: – I have OpenSSL 1.0.1c __

Slide 49

Slide 49 text

Why one-way flow is simpler? Server: – I have OpenSSL 1.0.1c __ – Can we upgrade to 1.1.0h?

Slide 50

Slide 50 text

Why one-way flow is simpler? Server: – I have OpenSSL 1.0.1c __ – Can we upgrade to 1.1.0h? – Maybe we should upgrade to 1.0.1u first?

Slide 51

Slide 51 text

Why one-way flow is simpler? Server: – I have OpenSSL 1.0.1c __ – Can we upgrade to 1.1.0h? – Maybe we should upgrade to 1.0.1u first? – Or can we upgrade to 1.0.2o, right?

Slide 52

Slide 52 text

Why one-way flow is simpler? Server: – I have OpenSSL 1.0.1c __ – Can we upgrade to 1.1.0h? – Maybe we should upgrade to 1.0.1u first? – Or can we upgrade to 1.0.2o, right? – Well, it probably depends on our current version version

Slide 53

Slide 53 text

Why one-way flow is simpler? Server: – I have OpenSSL 1.0.1c __ – Can we upgrade to 1.1.0h? – Maybe we should upgrade to 1.0.1u first? – Or can we upgrade to 1.0.2o, right? – Well, it probably depends on our current version version – What did we update last time?

Slide 54

Slide 54 text

Why one-way flow is simpler? Server: – I have OpenSSL 1.0.1c __ – Can we upgrade to 1.1.0h? – Maybe we should upgrade to 1.0.1u first? – Or can we upgrade to 1.0.2o, right? – Well, it probably depends on our current version version – What did we update last time? Docker: – I have OpenSSL 1.0.1c __ – Can we upgrade to 1.1.0h? – Yes! Simply setup your environment from scratch.

Slide 55

Slide 55 text

Why one-way flow is simpler? Server: Docker: Init State1 State2 Init State1 Init State2 No intermediate state

Slide 56

Slide 56 text

Render React https://reactjs.org/

Slide 57

Slide 57 text

Render React

Slide 58

Slide 58 text

Simplify React app

Slide 59

Slide 59 text

We are a small startup, not Facebook! I used React for demonstration purposes only. Yes, using SPA is complicated. But use appropriate tools to solve your problems.

Slide 60

Slide 60 text

React ___ JS ___ Internet ___ Software ___ World http://www.npmtrends.com/react-vs-@angular/core-vs-vue-vs-ember-source

Slide 61

Slide 61 text

React routing https://github.com/ReactTraining/react-router

Slide 62

Slide 62 text

Heaviest objects in the Universe Sun Neutron star Black hole node_modules

Slide 63

Slide 63 text

React routing

Slide 64

Slide 64 text

React routing

Slide 65

Slide 65 text

React routing

Slide 66

Slide 66 text

React routing

Slide 67

Slide 67 text

Separating React route files

Slide 68

Slide 68 text

Switching routes

Slide 69

Slide 69 text

Switching routes

Slide 70

Slide 70 text

Turbolinks vs React Turbolinks: – Received an event. – Let’s re-render the whole page. – Done, just replaced the whole HTML DOM body

Slide 71

Slide 71 text

Turbolinks vs React Turbolinks: – Received an event. – Let’s re-render the whole page. – Done, just replaced the whole HTML DOM body React: – Received an event. – Let’s calculate the final state in Virtual DOM (reconciliation). – Let’s quickly re-render only necessary elements in DOM.

Slide 72

Slide 72 text

Turbolinks vs React Turbolinks: – Received an event. – Let’s re-render the whole page. – Done, just replaced the whole HTML DOM body React: – Received an event. – Let’s calculate the final state in Virtual DOM (reconciliation). – Let’s quickly re-render only necessary elements in DOM. – We could pause until the new data is fetched in 3G (I/O). – We could re-render in smaller chunks during idle time only (CPU)

Slide 73

Slide 73 text

Adding static HTML

Slide 74

Slide 74 text

Adding static HTML

Slide 75

Slide 75 text

• What is GraphQL and why a graph, GraphQL specification • New blog application with Rails v5.2 • What is Webpack, Webpacker vs Sprockets • One-way data flow, React vs Turbolinks • Static HTML template Part 1: Bootstrapping simple application

Slide 76

Slide 76 text

• What is GraphQL and why a graph, GraphQL specification • New blog application with Rails v5.2 • What is Webpack, Webpacker vs Sprockets • One-way data flow, React vs Turbolinks • Static HTML template Part 1: Bootstrapping simple application

Slide 77

Slide 77 text

• GraphiQL – exploring automatically generated documentation • Adding models • GraphQL gem v1.8 • GraphQL API endpoint, schema, types, enums, arguments • How GraphQL is different from REST API and what are the benefits Part 2: Describing GraphQL schema

Slide 78

Slide 78 text

GraphiQL: in-browser IDE https://developer.github.com/v4/explorer/

Slide 79

Slide 79 text

GraphiQL npm package https://github.com/graphql/graphiql

Slide 80

Slide 80 text

Installing an npm package

Slide 81

Slide 81 text

GraphiQL route

Slide 82

Slide 82 text

New Rails models

Slide 83

Slide 83 text

Seeds

Slide 84

Slide 84 text

Preparing DB

Slide 85

Slide 85 text

GraphQL gem ___ http://graphql-ruby.org/

Slide 86

Slide 86 text

GraphiQL route

Slide 87

Slide 87 text

GraphQL schema

Slide 88

Slide 88 text

GraphQL Post type

Slide 89

Slide 89 text

GraphQL Types: Active Model Serializer on steroids • Declarative specification for available fields • Custom field implementation with Ruby instance methods • Strong type definitions, description for documentation • Type composition (relations) • Don’t worry about response root key names (GraphQL specification) • API consumers specify fields they need

Slide 90

Slide 90 text

GraphQL Post type

Slide 91

Slide 91 text

No over-fetching REST: GraphQL:

Slide 92

Slide 92 text

No over-fetching https://giphy.com/gifs/silicon-valley-3oD3YlNhSe7cqZOV6E

Slide 93

Slide 93 text

GraphQL User type

Slide 94

Slide 94 text

GraphQL User type

Slide 95

Slide 95 text

No under-fetching REST: GraphQL:

Slide 96

Slide 96 text

GraphQL enums

Slide 97

Slide 97 text

GraphQL arguments

Slide 98

Slide 98 text

GraphQL arguments

Slide 99

Slide 99 text

• GraphiQL – exploring automatically generated documentation • Adding models • GraphQL gem v1.8 • GraphQL API endpoint, schema, types, enums arguments • How GraphQL is different from REST API and what are the benefits Part 2: Describing GraphQL schema

Slide 100

Slide 100 text

• GraphiQL – exploring automatically generated documentation • Adding models • GraphQL gem v1.8 • GraphQL API endpoint, schema, types, enums arguments • How GraphQL is different from REST API and what are the benefits Part 2: Describing GraphQL schema

Slide 101

Slide 101 text

• GraphQL clients • Consuming GraphQL API with modern JavaScript tools • Client-side code generation • Seemless integration – contract testing Part 3: Consuming GraphQL

Slide 102

Slide 102 text

Why use GraphQL clients? • Data fetching • Managing state and caching data (Redux is not required) • UI framework integrations (React, Angular, Vue) • Managing websocket connections for GraphQL subscriptions • Query batching • Helpers for pagination • Dev tools for debugging and introspecting

Slide 103

Slide 103 text

• Framework agnostic • Very flexible, not opinionated • Incrementally adoptable • Big community Apollo Client ___ https://www.apollographql.com/client

Slide 104

Slide 104 text

Adding React Apollo https://www.apollographql.com/docs/react/

Slide 105

Slide 105 text

https://twitter.com/dan_abramov/status/984951104315195392 Installing npm packages

Slide 106

Slide 106 text

Configuring Apollo Client

Slide 107

Slide 107 text

Wrapping a component to get data

Slide 108

Slide 108 text

Defining GraphQL query

Slide 109

Slide 109 text

Loading GraphQL query https://github.com/apollographql/graphql-tag

Slide 110

Slide 110 text

Fetching data

Slide 111

Slide 111 text

Using the data

Slide 112

Slide 112 text

Code generation https://github.com/apollographql/apollo-codegen

Slide 113

Slide 113 text

Introspecting schema and building JS type definitions

Slide 114

Slide 114 text

Flow: incremental JS static type checking https://flow.org/

Slide 115

Slide 115 text

Adding type annotations

Slide 116

Slide 116 text

Server changes GraphQL schema

Slide 117

Slide 117 text

Client validates query and code even before releasing it!

Slide 118

Slide 118 text

• GraphQL clients • Consuming GraphQL API with modern JavaScript tools • Client-side code generation • Seemless integration – contract testing Part 3: Consuming GraphQL

Slide 119

Slide 119 text

• GraphQL clients • Consuming GraphQL API with modern JavaScript tools • Client-side code generation • Seemless integration – contract testing Part 3: Consuming GraphQL

Slide 120

Slide 120 text

With great flexibility on the client-side comes great responsibility on the server-side. Let’s make our GraphQL API more robust

Slide 121

Slide 121 text

• Error handling • Authorization • Monitoring • Solving N+1 queries Part 4: Making GraphQL API more robust

Slide 122

Slide 122 text

Error handling https://github.com/exAspArk/graphql-errors

Slide 123

Slide 123 text

Error handling

Slide 124

Slide 124 text

Error handling

Slide 125

Slide 125 text

Authorization https://github.com/exAspArk/graphql-guard

Slide 126

Slide 126 text

Pass current user through context

Slide 127

Slide 127 text

Define authorization logic

Slide 128

Slide 128 text

Customize authorization error handling

Slide 129

Slide 129 text

Authorization

Slide 130

Slide 130 text

Monitoring https://github.com/uniiverse/apollo-tracing-ruby

Slide 131

Slide 131 text

Collect trace data per field https://github.com/apollographql/apollo-tracing

Slide 132

Slide 132 text

Expose trace data through GraphQL extensions https://facebook.github.io/graphql/October2016/#sec-Response-Format

Slide 133

Slide 133 text

Apollo Engine https://www.apollographql.com/engine • Query execution tracing per field • GraphQL error tracking • Caching • Alerts • Free for up to 1 million requests per month

Slide 134

Slide 134 text

Send tracing data to Engine

Slide 135

Slide 135 text

Send tracing data to Engine https://github.com/uniiverse/apollo-tracing-ruby#engine-proxy

Slide 136

Slide 136 text

N+1 queries

Slide 137

Slide 137 text

N+1 queries

Slide 138

Slide 138 text

I know the answer! https://giphy.com/gifs/cbc-funny-comedy-mr-d-xT9DPFPfULYJHHrqN2

Slide 139

Slide 139 text

I know the answer!

Slide 140

Slide 140 text

Solving N+1 queries https://github.com/exAspArk/batch-loader

Slide 141

Slide 141 text

Tell GraphQL to consider BatchLoader instances as lazy objects

Slide 142

Slide 142 text

Batch and cache

Slide 143

Slide 143 text

Batch and cache

Slide 144

Slide 144 text

Batch and cache

Slide 145

Slide 145 text

Batch and cache

Slide 146

Slide 146 text

Batch and cache https://engineering.universe.com/batching-a-powerful-way-to-solve-n-1-queries-every-rubyist-should-know-24e20c6e7b94

Slide 147

Slide 147 text

Batch and cache https://engineering.universe.com/batching-a-powerful-way-to-solve-n-1-queries-every-rubyist-should-know-24e20c6e7b94

Slide 148

Slide 148 text

No N+1 queries! __

Slide 149

Slide 149 text

• Error handling • Authorization • Monitoring • Solving N+1 queries Part 4: Making GraphQL API more robust

Slide 150

Slide 150 text

• Error handling • Authorization • Monitoring • Solving N+1 queries Part 4: Making GraphQL API more robust

Slide 151

Slide 151 text

Takeaways • GraphQL is a specification • Getting the data you need, no under-fetching / over-fetching • Strong type system for documentation and seamless integration • Incrementally adoptable on client-side / server-side (7y old Rails app __) • Simpler to understand for junior developers: • Server-side: no routes, controllers, serializers, better composition • Client-side: no manual data fetching, mapping, caching (Redux)

Slide 152

Slide 152 text

Takeaways • GraphQL is a specification • Getting the data you need, no under-fetching / over-fetching • Strong type system for documentation and seamless integration • Incrementally adoptable on client-side / server-side (7y old Rails app __) • Simpler to understand for junior developers: • Server-side: no routes, controllers, serializers, better composition • Client-side: no manual data fetching, mapping, caching (Redux) Conceptual compression!

Slide 153

Slide 153 text

When to use GraphQL? Always

Slide 154

Slide 154 text

When to use GraphQL? Always

Slide 155

Slide 155 text

When to use GraphQL? • You have more than one API client (e.g. web + mobile app) • You care about latency and bandwidth (e.g. mobile networks) • You need a large API which you’re planning to change over time • You have multiple data sources (services, databases) and you need one API gateway

Slide 156

Slide 156 text

Thank you! https://giphy.com/gifs/student-JU6TzB6O9QCju

Slide 157

Slide 157 text

What we didn’t cover • Testing GraphQL • Pagination: limit / offset vs. cursor-based • Versioning, schema masking, stitching, delegation • Caching • Persisted queries • Query depth / complexity • Mutations for changing state on client-side / server-side • Subscriptions