Search code examples
reactjsreact-nativegraphqlexpoapollo

Apollo with multiple GraphQL endpoints


I need to use multiple GraphQL schemas, I currently have installed


expo: sdk 42 "@apollo/client": "^3.4.11", "apollo-link": "^1.2.14", "graphql": "^15.5.3",

As long as I use a single schema everything works fine: Declaration of a single schema

App.js

import { ApolloProvider, ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import { ApolloLink } from 'apollo-link';

const httpLink = createHttpLink({
    uri: `${serverBaseUrl}/client/graphql`,
  });


const authLink = setContext((_, { headers }) => {
    return {
      headers: {
        ...headers,
        /**@all headers*/
      }
    }
  });

const client = new ApolloClient({
   link: authLink.concat(httpLink),
   cache: new InMemoryCache(),
   credentials: 'include'
});

<ApolloProvider client={client}>
 /**@all*/

Query Example.jsx

import { gql, useQuery } from "@apollo/client";

  const E_QUERY = gql`
  query{
      example(sortBy: { field: "updatedAt", order: DESC }){
        _id
      }
  }
`;

const { loading, data } = useQuery(E_QUERY , {    
    fetchPolicy: "network-only",
  });

All good for now

but when I add multiple schemas it doesn't generate any error, it just keeps loading alone


App.js

const client = new ApolloClient({
    link: ApolloLink.split(
      operation => operation.getContext().clientName === "adminGQL",
      authLink.concat(httpLinkAdmin), 
      operation => operation.getContext().clientName === "agentGQL",
      authLink.concat(httpLinkAgent), 
      operation => operation.getContext().clientName === "client",
      authLink.concat(httpLinkAgent), 
    ),
    cache: new InMemoryCache(),
    credentials: 'include'
  });

Example.jsx

const { loading, data } = useQuery(EXAMPLE_QUERY , {    
    fetchPolicy: "network-only",
    context: { clientName: 'client' }
  });

thank you


Solution

  • The first error detected is that ApolloLink.split can only perform a comparison and it only has two possible cases (true or false) so it cannot be added more than two urls, so how will it be to add more than 2 urls?

    ApolloLink.d.ts

    static split(test: (op: Operation) => boolean, left: ApolloLink | RequestHandler, right?: ApolloLink | RequestHandler): ApolloLink;
    

    Starting from this point we have the solution as follows

    const client = new ApolloClient({
        link: ApolloLink.split(
          operation => operation.getContext().clientName === "adminGQL",
          authLink.concat(httpLinkAdmin), 
          authLink.concat(ApolloLink.split(
            operation => operation.getContext().clientName === "agentGQL",
            httpLinkAgent, 
            httpLink
          ))
        ),
        cache: new InMemoryCache(),
        credentials: 'include'
      });
    

    It may not be the best solution, but it was the one I was able to build. So new suggestions or solutions may be welcome.