GraphQL in Vue3 using Apollo
Today I am going to show you how to use GraphQL in a Vue3 web application.
To keep this blog post simple and focused on the topic only, I will assume that you know how to create a Vue 3 app using the composition API and what GraphQL is.
First of all we need to install the following packages:
npm install --save @apollo/client @vue/apollo-composable @vue/composition-api graphql graphql-tag react vue@3.0.11 --legacy-peer-deps
As you might have noticed, we need to install react as it's a dependency of the Apollo client. The --legacy-peer-deps
will allow us to install @vue/composition-api
as it's a dependency of @vue/apollo-composable
. And at the time of writing, vue@3.1.2 is not working properly with Apollo so we need to install vue@3.0.11.
At this point we are half way through the finish.
We now need to initialize the Apollo plugin and I like it to organize it this way:
Create a new folder called Plugins
and inside create this file useApolloPlugin.js
:
import { ApolloClient, InMemoryCache } from '@apollo/client'
const apolloClient = new ApolloClient( {
uri: 'https://yourservicedomain.com/graphql',
cache: new InMemoryCache(),
headers: {
"Authorization": "Bearer TO_ADD_FOR_TESTING_PURPOSES"
}
} )
export default apolloClient
In your app.js file write the following:
import { createApp, h } from 'vue'
import { provideApolloClient } from '@vue/apollo-composable'
import apolloClient from '@/Plugins/useApolloPlugin'
const app = createApp( {
setup () {
provideApolloClient( apolloClient )
},
...
} )
To simplify the GraphQL fetch handling process, I create a file in GraphQL/index.js
with the following content:
import { useQuery, useResult } from '@vue/apollo-composable'
import { watch } from 'vue';
export default {
runQuery ( query, model ) {
const { result } = useQuery( query )
watch(useResult( result, []), data => {
model.value = data
})
}
}
The above file will send the query and once we have a result, will set the value on the given reactive variable model
.
We can now start using Apollo to fetch queries, and this is how I like to do it:
<template>
<AppLayout>
<button @click="fetchItems">Fetch items</button>
<div v-for="item in items" :key="item.id">
{{ item }}
</div>
</AppLayout>
</template>
<script>
import { ref } from 'vue'
import { gql } from 'graphql-tag'
import GraphQL from '@/GraphQL'
export default {
setup () {
let items = ref( [] )
const fetchItemsQuery = gql`
query ItemsList {
items {
id
name
}
}
`
const fetchItems = () => GraphQL.runQuery( fetchItemsQuery, items )
return {
spaces,
fetchItems
}
}
}
</script>