Skip to content

TypeScript Consumer

Preface

This guide will explain how to fetch data from a GraphQL endpoint and map the response to a TypeScript model using Relay.

Info

Refer to the Relay Docs to learn more.

We will cover:

Alternative Options

If you are looking for alternative GraphQL clients, you may consider:

Dependencies

This guide assumes you have already set up Relay in your project. Relay is highly integrated with React, so you’ll also need the following packages:

  • react-relay for React integration with Relay
  • relay-runtime for core Relay functionality
  • babel-plugin-relay for compiling Relay queries

Setup Relay Environment

We initially must set up a Relay environment which allows Relay to access the GraphQL endpoint. In the root of src we create a RelayEnvironment.ts. In this file we are setup up a Relay environment for making GraphQL requests. The fetchFn function abstracts the networking stack, sending a POST request to the GraphQL endpoint with the query and variables while also allowing for extensions like rate limiting or custom error handling as needed. The createRelayEnvironment function initializes the Relay environment by combining the network layer (responsible for fetching data) and the store (which caches the data).

RelayEnvironment.ts

import {
    Environment,
    Network,
    RecordSource,
    Store,
    FetchFunction,
} from "relay-runtime";

const HTTP_ENDPOINT = "http://127.0.0.1:8000/graphql"; // assuming you are running any of the services from how to guides

const fetchFn: FetchFunction = async (request, variables) => {
    const response = await fetch(HTTP_ENDPOINT, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify({
            query: request.text,
            variables,
        }),
    });

    return await response.json();
};

function createRelayEnvironment() {
    return new Environment({
        network: Network.create(fetchFn),
        store: new Store(new RecordSource()),
    });
}

export const RelayEnvironment = createRelayEnvironment();

Info

Refer to the Relay Environment Docs to learn more.

Generate TypeScript Types

Relay generates TypeScript types automatically for your queries, based on the GraphQL schema. For example, if you are querying a Person type form the GraphQL schema, Relay will generate types for you.

query PersonQuery {
  person {
    id
    firstName
    lastName
  }
}

Relay will automatically generate a TypeScript type for this Query when you run the Relay compiler.

// __generated__/PersonQuery.graphql.ts

export interface PersonQuery {
  person: {
    id: string;
    firstName: string;
    lastName: string;
  } | null;
}

Fetch Data Using Relay

In Relay, we define our GraphQL queries within components using the useLazyLoadQuery or useFragment hooks. Relay then fetches and manages data for you.

To fetch data, we define a query in our component and use Relay's useLazyLoadQuery hook to execute it. The query is defined using the GraphQL tag provided by babel-plugin-relay.

Fetch Data with Relay

import { graphql, useLazyLoadQuery } from "react-relay";
import { PersonQuery } from './__generated__/PersonQuery.graphql'; // generated by relay compiler

const PersonComponent = () => {
    const data = useLazyLoadQuery<PersonQuery>(
        graphql`
        query PersonQuery {
            person {
            id
            firstName
            lastName
            }
        }
        `,
        {}
    );
    if (!data.person) {
        return <div>Loading...</div>;
    }
    return (
        <div>
            <h1>{data.person.firstName} {data.person.lastName}</h1>
        </div>
    );
};

export default PersonComponent;

Mapping the Response

With Relay, we don't need to manually map the response to TypeScript models as the Relay handles this internally and generates types for each query. Relay will ensure the data conforms to the types defined in your GraphQL schema. It will map the response to the PersonQuery type and ensure that your TypeScript code only access the fields that match the GraphQL schema, such as id, firstName and lastName. If the GraphQL schema changes or if there's a mismatch in types, Relay will flag it during compilation giving type safety.

If the Python graphQL service is running, PersonComponent should render:

foo bar