Setting up Vue-Apollo is straight forward with many excellent tutorials on line. In my current project I used the Vue CLI to install + set up. A little bit of tweaking for ensuring Auth token was always valid and it was good to go.
No drama
So everything it ticking along nicely when there was a requirement to iterate through an array of ID’s and fire off a graphQL query. Now there could be hundreds of ID’s to process.
Requirements
To run a graphQL query for each ID in an array and aggregate the results into a single collection.
Two possible ways of doing this. The first is to send one query at a time and manage its response – this proved slow and tricky keeping track of potential errors. The second is to let Apollo client handle the logistics using “BatchHttpLink” – it did require a bunch of reading and re-working the Apollo client. In the end batch processing has been working perfectly.
There was a 3rd option, change the Apollo server itself but that want an option.
Solution
My Vue-Apollo config is ./src/vue-apollo.ts
import VueApollo from 'vue-apollo'
import Vue from 'vue';
import { ApolloClient } from 'apollo-client'
import { ApolloLink, split } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { BatchHttpLink } from 'apollo-link-batch-http';
import { getMainDefinition } from 'apollo-utilities'
import { setContext } from 'apollo-link-context';
const AUTH_TOKEN = 'apollo-token'
const HTTP_END_POINT = process.env.VUE_APP_APOLLO_GRAPHQL_CLIENT_URI || "";
const authLink = setContext(async (_, { headers }) => {
return {
headers: {
...headers,
// This is calls a function to return a valid auth token
authorization: `Bearer ${ await Vue.prototype.$auth.getTokenSilently() }`
}
}
})
// Set up two different methods the Apollo client can use to handle queries
const httpLink = new HttpLink({ uri: HTTP_END_POINT });
// Add the auth header token
const httpLinkAuth = authLink.concat(httpLink);
// This is the magic batch processing set up
// Other options can be passed. E.g. batch size (default value is 10)
const batchLink = new BatchHttpLink({ uri: HTTP_END_POINT });
const batchLinkAuth = authLink.concat(batchLink);
const link = split(
// split based on operation type
({ query }) => {
const { kind, operation } = getMainDefinition(query)
return kind === 'OperationDefinition' && operation === 'subscription'
},
httpLinkAuth,
batchLinkAuth,
)
const client = new ApolloClient({
link: ApolloLink.from([link]),
cache: new InMemoryCache(),
connectToDevTools: true
})
// This is the bit you import into main.ts
export const apolloProvider = new VueApollo({
defaultClient: client
});
So far so good. Next how to call and respond to batched queries.
methods: {
fetchUsers() {
[
'6a1603c9-a613-4be5-ae92-123456789',
...
...
....
'ee55f518-3e65-4118-a0e8-987654321'
].forEach(id => {
this.$apollo.query({
query: USER_QUERY,
variables: { id },
})
.then(d => {
this.users.push(d.data.User)
})
.catch(e => console.log(e));
});
}
}