@adeira/relay is an opinionated wrapper around facebook/relay - a JavaScript framework for building data-driven React applications. Goal of this package is to create powerful yet simple to use Relay wrapper with great DX and additional useful features:
- all under one rooftop (simpler installation and setup)
- network fetching with retries and timeouts (see
@adeira/fetch)
- support for files uploading via GraphQL mutations
- query logging during development
- Relay compiler with ES6 output and source signing
- improved Flow types and sanity checks
More info about Relay, prior art:
Installation and Setup
@adeira/relay is meant to be drop-in replacement for facebook/relay to ease migrations back and forth (it's just all hidden under one rooftop with small DX tweaks and improvements).
In case you are migrating from facebook/relay: uninstall all the Relay related packages you installed manually (babel-plugin-relay, react-relay, relay-compiler, relay-config and relay-runtime). You should also remove custom flow-typed definitions for Relay. This package takes care about everything you need (only one dependency needed).
Installation
yarn add react react-dom @adeira/relay
Set up Relay with a single config file
Create a new file relay.config.js in your project root and configure some basics:
module.exports = {
src: './src',
schema: './data/schema.graphql',
exclude: ['**/node_modules/**', '**/__mocks__/**', '**/__generated__/**'],
};
Set up babel-plugin-relay
Add "relay" to the list of plugins in your .babelrc file:
{
"plugins": ["relay"]
}
Set up adeira-relay-compiler
{
"scripts": {
"relay": "adeira-relay-compiler",
"relay:schema": "adeira-fetch-schema --resource=http://… --filename=./data/schema.graphql"
}
}
Script relay:schema helps with schema fetching (and signing) and relay script runs the actual compiler using the config above.
Usage
First, you should set up Relay Environment somewhere in the root of your application. We provide useful functions createEnvironment and createNetworkFetcher which will set up everything for you:
import React from 'react';
import { createEnvironment, createNetworkFetcher } from '@adeira/relay';
function render() {
const Environment = createEnvironment({
fetchFn: createNetworkFetcher('https://graphql.example.com', {
'X-Client': '** TODO **',
}),
});
return (
<RelayEnvironmentProvider environment={Environment}>
<React.Suspense fallback={'Loading…'}>{/* your React application here */}</React.Suspense>
</RelayEnvironmentProvider>
);
}
Now, you can start fetching data in your React application:
import React from 'react';
import { graphql, useLazyLoadQuery } from '@adeira/relay';
export default function App(props) {
const data = useLazyLoadQuery(graphql`
query AppQuery {
allLocations(first: 20) {
edges {
node {
id
name
}
}
}
}
`);
return (
<ol>
{data.allLocations?.edges?.map((edge) => (
<li key={edge?.node?.id}>{edge?.node?.name}</li>
))}
</ol>
);
}
For more information on how to use Relay please follow the official Relay Guided Tour: https://relay.dev/docs/guided-tour/
Everything you find in the Relay Guided Tour should work with our drop-in replacement @adeira/relay (except you import everything from @adeira/relay package).
Tips and tricks
Tip 1: do not expose global Relay Environment
You should never import your custom environment directly when working with mutations or subscriptions. Try to prefer useMutation hook if possible or get the environment via useRelayEnvironment hook:
import { useRelayEnvironment } from '@adeira/relay';
function Component() {
const environment = useRelayEnvironment();
const handler = useCallback(() => {
commitMutation(environment, …);
}, [environment])
return (…);
}
Only this way you can be sure that your mutation/subscription is using the correct environment.
Tip 2: lazy, eager or debug logger?
You can change rich log output into browser console like this (the default is RelayLazyLogger):
import {
RelayLazyLogger,
RelayEagerLogger,
RelayDebugLogger,
} from '@adeira/relay';
const Environment = createEnvironment({
log: RelayLazyLogger,
});
Note: the logs are being printed only during development.
Tip 3: file uploading via GraphQL mutations
Apart from the actual mutation and variables, useMutation hook accepts also uploadables. Uploadables is a UploadableMap which is an object of File
or Blob.
@adeira/relay will automatically send the request as multipart/form-data instead of application/json when it detects uploadables, so you don't have to worry about anything.