Apollo Multiple Clients with React?

Rafael Nunes
Aug 9, 2018 · 5 min read

updated at: 06/08/2019

React + Apollo Client + GraphQL = ❤

This quick post explains how to use different Apollo clients in the same React application, but in the end, discuss other approaches when working on multiple GraphQL APIs. This is not intended to question the GraphQL philosophy by any means 😝!

I wrote this because I found myself questioning how could I use multiple clients to query different GraphQL APIs from my React application. It turns out there were lots of issues in Apollo GitHub project, discussing the need and presenting suggested implementations for it.

TL;DR: passing any ApolloClient instance to Query/Mutation/Subscription components as props works just fine! Check: https://github.com/peaonunes/apollo-multiple-clients-example

Some links to related issues, discussions, and proposals are listed below. Some of the old proposals indeed were merged and come along old react-apollo versions. However, the approach to using the Apollo client and querying changed a lot (for better) since 2.1.


Why would we need multiple clients?

Apollo Client accepts only one client uri on its initialization, therefore, it is meant to be used with one client at the time.

import ApolloClient from "apollo-boost";

const client = new ApolloClient({
uri: "https://48p1r2roz4.sse.codesandbox.io"
});

So if in your React application you need to retrieve data from two different GraphQL services, for example, you cannot use the same client or provider instance.

In my case specifically, I was just looking for a quick win implementation approach to get data from two GraphQL APIs to validate a solution. I was not worrying too much about schemas collision since the types, cache, state (…) would not overlap.

In my scenario, it would make sense to have a way of switching clients when querying APIs on Apollo. In the current approach though, you wrap your entire application with the ApolloProvider component which passes the client for the application through the context.

That actually makes it simple to query data using the Query Component, but it also means that the client provided via context is the only used when querying.

I spent some time looking through numerous issues and related projects and it turns out that there is a way of overriding the context client for Query and Mutation component passing another client through props 🎉 🎉 !

<Query client={anotherClient} query={query}>
{({ data }) => (<div>{data.name}</div>)}
</Query>

Update, Aug 2019: Although they have changed the implementation it still works. https://github.com/apollographql/react-apollo/blob/master/packages/components/src/Query.tsx#L17

This feature is not mentioned in any part of the official documentation. We can indeed pass any client for the components that they will give preference for the one passed via props order than via context. So we could make:

I have implemented a runnable example that uses two different clients in this repository: https://github.com/peaonunes/apollo-multiple-clients-example

Even though this approach is functional you should keep in mind that you won’t have Apollo features running applying for both clients unless you pass the same cache to the clients (that might be a risk in case of schema collision), manage other features will be by your own. Apollo features will get compromised and as the application grows your codebase becomes thicker and development will probably be slower.

What would be the ideal approach then?

Solving the problem in the Frontend

As a product of this article discussion some approaches have come up by folks who did their own abstractions/implementations for solving this issue.

Community own package implementations

Michael Duve, wrote react-apollo-multiple-clients a packaged that allows you to switch between clients. It considers multiple providers and provides you a HOC component that accepts a client prop to switch to the desired client consumer. Discussion

Paul Grieselhuber, suggested in his post a way where everything worked through a single client and allowed you to simply toggle on context to select a uri where the client will dispatch the requests. You can follow the discussion here.

Client-side schema stitching

Despite support for server side, it is not common to see people trying to solve the issue right on the client, there are some issues looking for or requesting stitching on client side, #797 for example.

The company Hasura, though, points out an implementation of client side schema stitching and it might be sufficient in your case.


Although I think that these approaches solve the problem I also think they can increase so much the complexity of the frontend application as the application grows. From my point of view, the work should be done on Backend by providing a unique interface for all the different APIs.

Gateways for Frontends

API Gateway is a known pattern with increasing adoption in our “microservice boom” age. API Gateway is a single interface between the services and clients.

It seems to be a consensus in the GraphQL world as well that the API Gateway is the way to go on connection with different GraphQL APIs. However sometimes going beyond that, since the Gateway itself can create a GraphQL interface for other REST and RPC APIs.

The real problem of serving different APIs through a unique gateway is how to manage and orchestrate different schemas.

Schema Stitching

The first attempt the Apollo team advocated for was Schema Stitching as I mentioned in this post before.

After some time of development and feedback from the community this approach was considered fragile and it is now deprecated.

Apollo Federation

Apollo recently launched a new concept for solving this problem of managing different schemas through a gateway which is called Apollo Federation.

“Apollo Federation is our answer for implementing GraphQL in a microservice architecture. It’s designed to replace schema stitching and solve pain points such as coordination, separation of concerns, and brittle gateway code.” James Baxley III

They have launched the Federation spec before and it already counts with implementations in some languages, apollo-gateway, for example. The idea is to have a gateway that composes the schemas and the federated services can connect with each other through keys (just like primary keys) and they are also able to extend types. All this just using regular GraphQL spec.

I recommend taking the time to watch the video below and spend some time playing around with this promising approach.

Apollo Federation — A revolutionary architecture for building a distributed graph

I personally tried it and I am seeing companies working on solutions based on this new approach. It is also notable that there are some challenges and space for other discussions like managing authentication/authorization, how flexible the gateway should be, etc. Hopefully, the Federation get evolving based on feedbacks from the community and companies.


Conclusion

As I mentioned before this post is not about questioning the "right" way on requesting multiple GraphQL APIs, but it is about pointing out approaches that hopefully might be enough for solving the issues of today.

I think the whole discussing about using API Gateways and managing different GraphQL schemas is just at the beginning and the community will work on nicer and better solutions.

I am more than happy to read suggestions and engage discussions so leave your thoughts below.

Open GraphQL

Anything & Everything GraphQL

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store