DEV Community

Cover image for Lazy Load Apollo Link in Apollo Client
Daishi Kato
Daishi Kato

Posted on • Originally published at blog.axlight.com

Lazy Load Apollo Link in Apollo Client

10 lines of code to help

Introduction

This is a short post about my small library.

Apollo Client is a library for GraphQL. Apollo Link is an interface to extend Apollo Client.

Typically, you would initialize apollo client like this.

import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';

const cache = new InMemoryCache();
const link = new HttpLink({ uri });

const client = new ApolloClient({
  cache: cache,
  link: link,
});
Enter fullscreen mode Exit fullscreen mode

I want to define the link in another file and lazy load it, because it is not an HttpLink but a complicated large link.

How to use

We use dynamic imports for this.

Let's assmume we have link.js file that exports an apollo link. It'd be nice to dynamic import it.

import { lazy } from 'apollo-link-lazy';

const link = lazy(() => import('./link'));
Enter fullscreen mode Exit fullscreen mode

import() returns a promise, but there's no await. How is this possible?

How to implement

Interestingly, Apollo Link is asynchronous by nature. However, it's not promise based. It has observable interface.

So, all you need is to covert a promise into an observable.

Here's the code.

import { ApolloLink, fromPromise, toPromise, Observable } from 'apollo-link';

export const lazy = (factory) => new ApolloLink(
  (operation, forward) => fromPromise(
    factory().then((resolved) => {
      const link = resolved instanceof ApolloLink ? resolved : resolved.default;
      return toPromise(link.request(operation, forward) || Observable.of());
    }),
  ),
);
Enter fullscreen mode Exit fullscreen mode

Luckily, apollo-client exports fromPromise and toPromise utility functions. Hence, it can be implemented so easily.

A little trick here is to support both ApolloLink promises and default exports.

Demo

I developed this code as a library.

https://github.com/dai-shi/apollo-link-lazy

You can install it and use it. It supports TypeScript.

Here's also a demo in codesandbox.

https://codesandbox.io/s/github/dai-shi/apollo-link-lazy/tree/master/examples/02_typescript

Closing notes

As my motivation was code splitting, supporting default exports like React.lazy was actually enough. Because it also supports direct promises, we can use it for any async initialization like the following.

import { lazy } from 'apollo-link-lazy';

const link = lazy(async () => {
  // await ...
  return new ApolloLink(...);
});
Enter fullscreen mode Exit fullscreen mode

I hope this may help other developers who try lazy loading of apollo links.


Originally published at https://blog.axlight.com on January 10, 2020.

Top comments (0)