Apollo Multiple Clients with React?
This quick post explains how to use different Apollo clients in the same React application, but in the end shows some ideal and other proposed 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 on Apollo github project, discussing the need and presenting suggested implementations for it.
TL;DR: passing any custom client to Query or Mutation component as props works just fine! https://github.com/peaonunes/apollo-multiple-clients-example
Below some links of issues, discussions and proposals that I mentioned. Some of old proposals indeed were merged and come along old
react-apollo versions. However, the approach on using the Apollo client and querying changed a lot (for better) since
Why would we need multiple clients?
Coding in the whole microservices revolution left me in the doubt on how should I query different GraphQL APIs from my React application.
In my case specifically I was just looking for a quick win implementation approach to use in a real product validation. Not really worrying too much about different schemas since the queries would not overlap, cache, state or any control over the main features that Apollo provides us.
In this scenario, it would makes sense to have a way of switching clients when querying APIs on Apollo. In the new approach though, you wrap your entire application with the
ApolloProvider component which passes the client for the application through the context. As you can see in Creating Provider.
That actually makes it really simple to query data using the Query Component, but it also means that the client provided is the only considered when querying.
After looking through numerous issues and related projects it turns out there is a way of overriding the context client for
Mutation component passing other client through props 🎉 🎉 ! The following lines are from
react-apollo source code, current on version
Although there are no mentions for this feature in 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
The approach is functional, but you have to 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 definitely get compromised and as the application grows your codebase becomes thicker and development will probably be slower.
What would be the ideal approach then?
There are some approaches while working with GraphQL stack to deal with multiple APIs. It seems to be a consensus that when it comes to querying different GraphQL APIs you should manage it through a Gateway API.
Gateway API would handle any communication between the user friendly application and others APIs. Managing queries and schemes in order to serve the user queries. You are now probably asking yourself:
How could I query different APIs with an unique query to the Gateway? Or should I request them always apart?
To solve this question the Apollo has an implementation for Schema Stitching.
Schema stitching is the process of creating a single GraphQL schema from multiple underlying GraphQL APIs.
This is the current best way of supporting multiple GraphQL APIs although it requires more work on Gateway to manage schemas and correctly serve queries to applications. Thankfully the documentation is clear and easy to follow and the community itself feedbacks with tutorials such as the following:
Announcing graphql-tools 3.0 with schema transformations and simpler delegationblog.apollographql.com
Micro-services have been gaining popularity because of their awesome architecture to modularize services and provide a…codeburst.io
Despite the full 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.
Client side schema stitching is not recommended and there is no official documentation for following this approach. The following great post/project though presents a way of doing it using
graphql-tools , showing us that is indeed possible to implement it.
This blogpost talks about the why and how of:blog.hasura.io
Client side schema stitching can increase the complexity of the frontend application as the application grows. And maybe we might not be able to keep up with new supported features since it is not the officially recommended approach. The developers of
graphql-tools might not consider use cases like that. Beyond that would have to handle two clients or two links state. And if you are working with internal APIs that should not be reachable from the end user then this would be an issue.
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 hear suggestions so leave your thoughts below.