I’m pretty new to apollo and react native. I’m working on a project where I need to use graphql subscriptions and use graphql queries, which need authentication. From the apollo docs I had set-up my client.ts like:
import { ApolloClient, split, HttpLink, InMemoryCache } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";
const wslink = new GraphQLWsLink(
createClient({
url: "ws://localhost:4000/subscriptions",
}),
);
const httpLink = new HttpLink({
uri: 'http://localhost:4000/graphql'
});
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wslink,
httpLink,
);
export const client = new ApolloClient({
cache: new InMemoryCache(),
link: splitLink,
});
but I need to add the authentication. The documents only mention authentication with this type of setup for the subscription aspect of the code:
const wslink = new GraphQLWsLink(
createClient({
url: "ws://localhost:4000/subscriptions",
connectionParams: {
authToken: user.authToken,
},
}),
);
which doesn’t help me and gives me an error because user
is unknown. The apollo docs give:
import ApolloClient from "apollo-client";
import { HttpLink } from "apollo-link-http";
import { ApolloLink, concat, split } from "apollo-link";
import { InMemoryCache } from "apollo-cache-inmemory";
import { getMainDefinition } from "apollo-utilities";
const httpLink = new HttpLink({ uri: process.env.VUE_APP_API_TARGET });
const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization to the headers
const token = localStorage.getItem('token');
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : "",
},
});
return forward(operation);
});
export const apolloClient = new ApolloClient({
link: concat(authMiddleware, httpLink),
cache: new InMemoryCache(),
});
as an example of how to add in the authentication aspect. What I’m having trouble with is how do you combine the two? Currently, I have:
import { ApolloClient, split, HttpLink, InMemoryCache } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { ApolloLink, concat} from "apollo-link";
import AsyncStorage from '@react-native-async-storage/async-storage';
import { GraphQLWsLink } from "@apollo/client/link/subscriptions";
import { createClient } from "graphql-ws";
const wslink = new GraphQLWsLink(
createClient({
url: "ws://localhost:4000/subscriptions",
}),
);
const httpLink = new HttpLink({
uri: 'http://localhost:4000/graphql'
});
const authLink = new ApolloLink((operation, forward) => {
const token = /*await*/ AsyncStorage.getItem('token');
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : "",
},
});
return forward(operation);
});
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wslink,
httpLink,
);
export const client = new ApolloClient({
cache: new InMemoryCache(),
link: splitLink,
});
In export const client = new ApolloClient({cache: new InMemoryCache(), link: splitLink, });
, I tried changing it to link: concat(authLink, splitLink)
, but that gives errors
"message": "Type 'ApolloLink' is missing the following properties from type 'ApolloLink': onError, setOnError",
and
"message": "Argument of type 'ApolloLink' is not assignable to parameter of type 'ApolloLink | RequestHandler'.\n Type ... ApolloLink'.\n Types of property 'split' are incompatible.\n
I also tried replacing httpLink
in const splitLink...
with , but that gave the errors:
"message": "Argument of type 'ApolloLink' is not assignable to parameter of type 'ApolloLink | RequestHandler | undefined'.\n Type 'ApolloLink' is missing the following properties from type 'ApolloLink': onError, setOnError",
and
"message": "Argument of type 'HttpLink' is not assignable to parameter of type 'ApolloLink | RequestHandler'.\n Type 'HttpLink' is not assignable to type 'ApolloLink'.\n Types of property 'split' are incompatible.\n...
Does anyone know how to do this? I would really appreciate any help or advice. Thank you!