codename “ ” is a new version of the popular library used at Facebook. It was redesigned with extensibility in mind, making it super flexible for integrating into any kind of web app, including (or universal) web applications. But first… Relay Modern GraphQL client isomorphic Why GraphQL? Well, if you look around, you will notice that GraphQL technology, which was also incubated at Facebook, is de-facto becoming the standard in developing backends for web and mobile apps, replacing RESTful APIs, JSON APIs, OData, and other similar specs — mainly because GraphQL is oriented towards developer experience and performance. Facebook developers absolutely nailed it. Take a look at GitHub’s GraphQL implementation as an example — + , where you can see how it works “live” and try executing a couple of sample queries. Give that link to a front-end developer that never heard about GraphQL, and within a couple of hours, he will be able to grasp the central concepts, start using it, and get things done ^_^ docs playground If you’re still thinking about what tech to use for building a for your next app, please look no further, GraphQL is an excellent choice for that use case. Also, it works perfect for building API gateways in microservice based architectures. data API server So, the question is not whether you need to use GraphQL or not :) But instead, which GraphQL client library best suits our project? At a bare minimum, you could just use . Let’s see what it looks like. You start by creating a couple of helper methods — , , etc. HTML5 Fetch API fetchQuery() commitMutation() As you can see, the package provides just one top-level React component — and three helper functions that are intended to be used for wrapping React components into Relay-enabled higher-order components. That’s it! The remaining five fields ( , etc) are simply re-exports from the module. react-relay QueryRenderer graphql fetchQuery relay-runtime Well, actually exposes much more API methods and fields in and namespaces. But you don’t want to look into those unless you’re working with a legacy codebase that’s built on top of Relay . Now let’s see how to integrate Relay “Modern” into your project. react-relay react-relay/classic react-relay/compat v0.x How to get started with Relay.js I assume that you’re already familiar with , and and have a basic project structure using this stack. If you’re not a big fan of React, I think that the code samples below can be applied to another front-end framework or library as well with a few minor tweaks. React Babel Node.js You start by installing all the packages mentioned previously by running: yarn install relay-runtime@1.0.0-rc.3yarn install react-relay@1.0.0-rc.3yarn install relay-compiler@1.0.0-rc.3 --devyarn install babel-plugin-relay@1.0.1-rc.3 --dev Including into the list of plugins in your Babel configuration file (normally or ): babel-plugin-relay .babelrc .babelrc.js Adding an npm script that will run Relay Compiler. So, the file in the root of your project would contain the following entries: package.json Now you need to copy and paste GraphQL schema from your data API server into your project by saving it to file (see ). This file is going to be used by Relay Compiler. And, as a side benefit, having this text-based schema (as opposed to JSON) under the source control will allow you and your front-end team to easily see how your GraphQL model evolves over time. Feel free to automate this task if needed. src/schema.graphql example Now you can try inserting some GraphQL queries in your code (inside the folder) and run command that will compile these text queries into . src yarn run relay JavaScript Alternatively, you can run Relay Compiler in watch mode: yarn run relay -- --watch Just keep in mind, that if you try to use some fields in your GraphQL queries that are missing in the file, Relay Compiler with throw an error. src/schema.graphql How does a GraphQL query must look like? You need to import object from either or module. And use with it. Here is an example: graphql relay-runtime react-relay tagged template literals Let’s assume for a moment that your file contains a schema with and top-level fields. Then if you would run , it would generate file in the same folder with the source file containing that GraphQL query. And after you compile your original source code with Babel, the tagged template literal string above will be replaced with . src/schema.graphql viewer posts yarn run relay __generated__/Example.graphql.js const query = () => require('__generated__/Example.graphql') An important thing to note is that Relay Compiler won’t work if your code contains anonymous queries or fragments such vs . query { viewer { email } } query ExampleQuery { viewer { email } } You can compose a top-level GraphQL query from fragments referring those fragments by their names. For example: Even if these exact same queries would be located in different files, Relay Compiler is smart enough to build the dependency tree, compile and optimize them. That’s why it requires all the queries and fragments to have their own unique names. Now, in order to pull data for all the components in the example above ( , , ), we need to fetch data only for the top-level query as the following code demonstrates: Layout Toolbar PostList Don’t pay much attention to the render function, but instead see how the helper method from the module is being used. fetchQuery() relay-runtime You may wonder, where is the variable coming from? In order to use Relay you need to initialize the so-called Relay environment. Luckily, the module provides all the necessary tools for that. This “environment” will slightly differ depending on whether your code is being executed in a browser or Node.js environment. environment relay-runtime For example, in a browser you may want to use HTML Fetch API in combination with polyfill and on the server, you can use the module that has exactly the same API but is designed for running in Node. Thanks to Webpack and module, you don’t have to think much about how to bundle the right library into your production code, it’s just as simple as doing . [whatwg-fetch](https://github.com/github/fetch) [node-fetch](https://github.com/bitinn/node-fetch) [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) import fetch from 'isomorphic-fetch' What else would differ? The base URL of your GraphQL endpoint. For example, in a browser Relay may fetch data from the endpoint, using a URL path string relative to your website’s domain name. But on the server, it must be a full URL, something like . /graphql http://api:8080/graphql Most likely you will want to create a factory method that given a base URL and a couple of other options will initialize the correct React environment plus a couple of helper methods to be used in either client-side or server-side code. Here is how it may look like: See src/api.js in https://github.com/kriasoft/react-starter-kit This factory method initializes Relay environment as well as binds it to the , methods so you don’t need to pass it every time you need to send a GraphQL query to the server. Here is an example of how it can be used: fetchQuery() commitMutation() Relay ❤ React Now let’s see how to decorate your React components with GraphQL query fragments, so that you wouldn’t need to manually pass all the props down the UI hierarchy, but let Relay to lookup the required data automatically per component. In order to do so, all you need to do is to use one of these three helper methods from module: react-relay — Composes a React component class, returning a new class ( ) that intercepts props, resolving them with the provided fragments and subscribing for updates. **createFragmentContainer()** [FragmentContainer](https://facebook.github.io/relay/docs/fragment-container.html) — Wraps a React component class into that first renders like a regular but has the option to execute a new query with different variables and render the response of that query instead when the request comes back. **createRefetchContainer()** [RefetchContainer](https://facebook.github.io/relay/docs/refetch-container.html) FragmentContainer — Wraps a React component class into that is designed to simplify the workflow of loading more items in a list — in many cases, we don't want to fetch all the data at once but lazily load more data. It relies on a GraphQL server exposing connections in a standardized way. For a detailed spec, please check out . createPaginationContainer() [PaginationContainer](https://facebook.github.io/relay/docs/pagination-container.html) this page Where is the name of the fragment, by convention it uses the name of the file (Toolbar) + underscore + the name of property under which that data must become available via . Toolbar_viewer this.props When you initialize this component, you need to pass prop containing record ID and will pull all the required fields from local Relay store by that ID ( and in that case). For example, in the parent component you would need to instantiate like this: viewer={…} FragmentComponent email isAdmin Layout Toolbar If, instead of , you name your fragment just , then the field is going to be available via (versus ). Layout_viewer Layout language this.props.data this.props.viewer OK, now let’s see how to integrate Relay with a single-page application router. Relay ❤ Universal Router As was mentioned previously, Relay comes with top-level component the purpose of which is to mount some temporary markup into the DOM, e.g. “Loading…”, given a top-level GraphQL query, start fetching required data from the server, and once data fetching is complete, render the actual application screen (page). [QueryRenderer](https://facebook.github.io/relay/docs/query-renderer.html) I’m sure this class does not suit all type of apps well, most likely you will want to either copy-paste and customize it for your app, or even use an alternative solution that will serve the similar purpose. QueryRenderer In the case of isomorphic apps, there is no need in rendering a temporary “Loading” screen. And also, it might be a better idea to pre-load all the data rendering your app with React. Let’s see how to implement that by using library — that might be already familiar to you via project. before [Universal Router](https://github.com/kriasoft/universal-router) React Starter Kit If you never heard about Universal Router, it’s a simple middleware-style routing solution that is framework agnostic (works well with any front-end framework) and purposely looks pretty much similar to the Express.js router making it simpler to adopt in isomorphic web apps. You need to compile a list of routes as a normal JavaScript array, where each item has , and optionally properties. A typical route may look like this: path action children Where argument is the exact same object that we initialized in one of the previous examples being passed to the route handler ( ) method as a context variable. api action() You initialize a router by calling and then execute its ) method to find and execute a route that matches the provided URL path string. Then all you need to do is just to render the returned React component to DOM on the client or into an HTML string on the server as the following sample code demonstrates: new Router(routes) .resolve({ path, …context } Summary Relay “Modern” is really great. The code samples above demonstrate how easily it can be integrated into any project (not necessarily React). Even if you start by using its basic features, you will still be able to write data fetching related code much more efficiently than without Relay. In the future posts, I will try to cover more advanced Relay features. Stay tuned :) And if you want to see a working example of React+Relay integration, please visit project on GitHub. Also, there is a sibling repo — that may help you to build a GraphQL API backend. I’m quite successfully using these two boilerplates in all my projects, so if you need any advice, don’t hesitate to get in touch on Twitter ( ). React Starter Kit Node.js API Starter @koistya