Skip to content
/ relay Public

Highly opinionated Relay wrapper. This repository is automatically exported from https://github.com/adeira/universe via Shipit

License

Notifications You must be signed in to change notification settings

adeira/relay

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@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.

Installation and Setup

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 where is your source code and GraphQL schema:

module.exports = {
  // Configuration options accepted by the `relay-compiler` command-line tool and `babel-plugin-relay`.
  src: './src',
  schema: './data/schema.graphql',
};

Set up babel-plugin-relay

Add "relay" to the list of plugins in your .babelrc file:

{
  "plugins": ["relay"]
}

Set up Relay Compiler

TKTK

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';

const Environment = createEnvironment({
  fetchFn: createNetworkFetcher('https://graphql.example.com', {
    // … additional HTTP headers if you want …
  }),
});

function render() {
  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) {
        id
        name
      }
    }
  `);

  return data.allLocations?.map((location) => {
    return <div key={location?.id}>{location?.name}</div>;
  });
}

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). Additionally, you can observe Relay logs in your dev console:

Relay Logger

Error handling

@adeira/relay forwards all successful responses (even when they are partial with errors) to the application code. This allows you to render the layout partially by getting the data via useLazyLoadQuery or in a callback onCompleted when calling a mutation.

Optionally, server can also specify whether the error is critical or not by sending a severity in the error's extensions entry:

{
  data: '…',
  errors: [
    {
      message: 'some critical server error message',
      locations: [{ line: 5, column: 5 }],
      path: ['commerce', 'products'],
      extensions: {
        severity: 'CRITICAL', // <<<
      },
    },
  ],
}

In this case, @adeira/relay will try to halt the application by throwing the error via useLazyLoadQuery (you should use an ErrorBoundary to catch it) or by calling a callback onError when calling a mutation.

This is particularly useful in situations when server would return a partial response, however, the error is so severe that we should not even attempt to partially render it.

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(() => {
    // For example, can be used to pass the environment to functions that
    // require a Relay environment (not needed with `useMutation` hook).
    commitMutation(environment, );
  }, [environment])

  return ();
}

Only this way you can be sure that your mutation/subscription is using the correct environment.

Tip 2: 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.

More info about Relay, prior art

About

Highly opinionated Relay wrapper. This repository is automatically exported from https://github.com/adeira/universe via Shipit

Resources

License

Stars

Watchers

Forks