A quick field guide to using Remix with Apollo GraphQL
We took Remix for a test drive and found it fun and concise. It cuts out a lot of the bloat that comes with wiring a typical React app and backend together.
What makes Remix a different kind of React framework is that it’s primarily a server-side rendered framework. On the first page load the page is pre-rendered on the server, which ensures a super-fast load time. Only once the HTML page is rendered, is the JS loaded and the app is hydrated. Any navigation from this point on is done using JS and without a full page reload. Remix gives you the best of both worlds out of the box. The starter docs also provides a comprehensive guide on how quickly you can start up a functioning Remix app.
In Remix you use the loader function to specify code that should be run on the server. This means you can make direct calls to your database or other API to fetch data. But if you already make use of Apollo and have a schema, it is also possible to use Apollo client in the Remix backend. Even better, if you use Apollo SchemaLink you will avoid the additional network hop to a separate GraphQL backend.
We’re going to show you how easy it is to plug Apollo into Remix. But before we do, let’s quickly dig into how Remix data loaders work.
What are loaders and how loaders work
loaders in Remix is a function that gets called on the server before rendering to provide the route with the required data.
To use loaders, you'd need to import
useLoaderData from Remix. The
loader function runs on the server-side, meaning that sensitive data can remain protected if needed.
Here is an example of how to import a loader and use it in a function:
That's basically how to import and use Remix loaders in a nutshell. Here is an example of some mock data being returned by the loader and used by the route.
But how do we incorporate a real database with it?
Using Apollo GraphQL with Remix loaders
Apollo GraphQL's client library has a schema link functionality that lets you create mock and server-side renders. This works hand-in-hand with Remix's
loader, which also supports async.
Here is an example of a
loader with async:
To create a schema link with Apollo GraphQL, first, you need to install
@apollo/client to your Remix project.
In addition to this, you will also need some GraphQL tools and utilities. Here is the complete npm list for everything that you need to load GraphQL data to your Remix app.
To get started, set up your schema. A schema sets up the metadata for what your data should look like. It defines the types and fields that are expected by the data. Here is an example of a GraphQL type:
A schema file is typically called schema.ts for quick identification. If you are trialing this out on a Remix app, you can put the following code inside a
grapql folder under the app folder. Here is an example of a GraphQL schema:
Now, we can make a GraphQL resolver with mock data, accessible via
@graphql-tools/utils. This resolver will pass the processing over to our route when called. Here is an example of the GraphQL resolver:
To connect the above resolver with the schema, go back to your schema file and invoke
makeExecutableSchema(). This function lets you create
GraphQLSchema instance. Here is the function in action (and complete schema example code):
To create server-side rending using Apollo, create a client that will use the loader above.
To call our GraphQL client, navigate back to your Remix code and use the loader function. This will allow you to load your mock data on the server side. Here is an example what it looks like:
And that's basically it!
Here is a link to our GitHub repo with a working Remix app that uses the above implementation.
Overall, using a schema link with mock data instead of using a network call can help slim down the development process. Remix, by design, is highly efficient for creating rapid prototypes. At a minimum, incorporating Apollo GraphQL only requires a schema, a resolver, and a client.