Relay/GraphQL Cheatsheet #1
Summary: Relay/GraphQL is a great piece of technology that simplifies front-end (& backend too) programming: after defining the GraphQL data schema of your backend, you only need to declare data that is required by your client-side UI (namely React), and the Relay code is entirely responsible for efficiently fetching & caching data required over the lifetime of a user’s web session. The flip-side is the learning curve can be daunting. We summarize the most important Relay/GraphQL concepts into a 6-diagram cheatsheet, which clearly color-codes how the server-side GraphQL schema, the client-side Relay Route, the Root React Component with its Relay Container, and its child component with its Relay Container, are bound together. In the upcoming part of this series we will cover mutation (the term used to describe updating server-side data), and other advance concepts.
We will introduce the concepts in this order:
- Object-Relational Mapping (ORM)
- GraphQL schema
- Relay Root Container
- Relay Route
- Root React Component (with its Relay Container)
- Child component (with its Relay Container)
Let us get started!
The database holds the relationships between different types of objects.
Example: This DB holds relationships between tea stores and the teas they sell.
Object-Relational Mapping (ORM)
ORM introduces classes that can be instantiated, and the instantiated objects contain methods/fields that facilitate navigating the various DB objects and their relationships.
Example: We can instantiate a tea store by providing its domain name to the class method ‘find_by_domain’, and from the instantiated tea store object, we can retrieve the tea objects using the field ‘teas’.
We declare a hierarchical (an important property) GraphQL schema (on the right of diagram below) with mappings to the ORM, or other data sources (on the left of diagram below), to inform the GraphQL server how to resolve the schema attributes.
Relay Root Container
TeaStore Relay Root Container (green) binds the TeaStore Root React Component (red) together with the GraphQL query to pull down data through TeaHomeRoute Relay Route (purple).
Relay Route & Root React Component
Relay is based 2 important ‘patterns’:
- Each React component is co-located with a Relay Container which holds its data declaration
- The Relay Container data declaration is rooted at a certain part of the data declaration of its parent container, which we elucidate below
We collapse the Relay Root Container (green), described in the previous diagram, so that we can focus, and expand on the two components that it binds together: the TeaHomeRoute (Relay Route in purple) and the TeaStore (Root React Component in red).
Note how the Relay Route only declares the point at which the GraphQL data requirements is rooted at: ‘store’ (bold maroon). The Relay Route delegates to the Root React Component, or more specifically its co-located Relay Container (bottom part of red text) to declare the data the Root React Component (top part of red text) needs: ‘domain’ (bold purple), and ‘teas’ (bold orange) — pattern #1. Take note of how the data declarations are then used within the Root React Component (top part of red text).
The Root React Component’s Relay Container data declaration is rooted at the higher-level container’s (the Relay Route) data declaration: ‘store’ (bold blue) — pattern #2.
Root React Component & Child
Finally, we shrink the Relay Route (purple), so that we can expand, and focus how the Root React Component (red) delegates data declaration duties to its child: Tea (orange). The child’s Relay Container (bottom part of orange text), declares the attributes tea ‘name’ (bold cyan), ‘steepingTime’ (bold black) that is required by its co-located React Component (top part of orange text) — pattern #1. Take note of how the data declarations are then used within the child (top part of orange text).
The child’s Relay Container data declaration is rooted at the higher-level container’s (the Root React Component) data declaration: ‘tea’ (bold gray) — pattern #2.
Relay is responsible for consolidating all data declarations from the Root React Component to its multi-level children (if they exist) so that it can perform a single GraphQL query (a single round-trip) to retrieve all the required data.
If the GraphQL schema had other pieces of data, e.g., store physical address, or tea leaf size, etc. they will never by requested by Relay in this scenario since no React components declared the need for them.
We hope that this cheatsheet helps you understand how Relay works, and it is useful as a reference whenever you create or debug a Relay/GraphQL-based React component. Please tell us how we can improve this cheatsheet.