Introduction
Good time of the day, friends!
Today I want to show you how to set up Apollo GraphQl in a Nuxt application, where nuxt will take care of both client side and server side. As a result, we will have a complete framework for developing a full-featured application.
I have prepared a ready-made example which you can pick up and feel in parallel with the reading. In it you can find server settings, client settings and some examples of Apollo usage.
The purpose of this article is to give brief instructions on how to quickly set up Apollo GraphQl in a Nuxt application.
I will be as brief as possible, strictly and to the point.
Let's begin!
Installing packages
We will need the following list of packages:
- apollo-server-express - a package which will provide apollo support on the server.
- @nuxtjs/composition-api - to support version 3 of Vue in Nuxt.
- @nuxtjs/apollo - wrapper around the vue-apollo plugin, to work with Nuxt.
- @vue/apollo-composable - adds Apollo GraphQL helper functions for Nuxt Composition API.
Open the terminal and install the packages
npm i -S apollo-server-express @nuxtjs/composition-api
@nuxtjs/apollo @vue/apollo-composable
Server configuration
In case you didn't know, nuxt uses the express.js server to render pages. It is necessary to prepare html files beforehand, thus solving SEO problems. This is how SSR mode works in nuxt.
But nuxt server can be used not only for rendering html files, but also for its own purposes, for example, to create a simple API. That's what we'll do today.
Let's start by creating a structure for the server.
In the root of the project, create a server folder in which we add the index.js file. This file will be the entry point for the server.
Let's add this code to it
const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const cors = require('cors');
const typeDefs = require('./typeDefs');
const resolvers = require('./resolvers');
const server = new ApolloServer({ typeDefs, resolvers });
const app = express();
app.use(cors({
origin: 'http://localhost:3000',
credentials: true,
}));
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(server.getMiddleware())
module.exports = app;
In the code above, we imported apollo-server-express, which allows us to work with Apollo GraphQL on the server. Be sure to add a CORS to protect against foreign domain queries. Let's configure all this and return an instance to be run by the nuxt server.
Now, to tell nuxt which file to run as a server, go to the nuxt.config.js file and add the new configuration there
...
/*
** Server middlewares
*/
serverMiddleware: [{ path: '/', handler: '~/server/index.js' }],
...
The serverMiddleware option allows us to register additional routes without having to use an external server. Simply put, this option is exactly what gives us the ability to connect to a nuxt server.
This completes the server setup.
Client configuration
1. Let's start by setting up @nuxtjs/composition-api
To do this, go to the nuxt.config.js file, which is located at the root of the project, find the modules: [] block and connect Nuxt Composition Api there
...
modules: [
'@nuxtjs/composition-api/module'
],
...
Thus, Composition Api will be available globally in all components.
2. Next we will configure @nuxtjs/apollo
The @nuxtjs/apollo plugin should also be added to modules: […]
...
modules: [
'@nuxtjs/composition-api/module',
'@nuxtjs/apollo'
],
...
After that, let's add settings for it, where we specify a link to the API, caching settings, hedges and other stuff.
Create a new folder in the root of the project called graphql. It will store everything related to graphql.
In the same folder, create an index.js file, the entry point from which the @nuxtjs/apollo plugin will pull settings for itself.
Let's add the following code to the file
import { HttpLink } from 'apollo-link-http'
import { setContext } from 'apollo-link-context'
import { from } from 'apollo-link'
import { InMemoryCache } from 'apollo-cache-inmemory'
export default ctx => {
const ssrMiddleware = setContext((_, { headers }) => {
if (process.client) return headers
return {
headers
}
})
const httpLink = new HttpLink({
uri: process.env.nuxtApiUrl,
credentials: 'include'
})
const link = from([ssrMiddleware, httpLink])
const cache = new InMemoryCache()
return {
link,
cache,
defaultHttpLink: false
}
}
The packages that are plugged in at the beginning of the file were installed with the @nuxtjs/apollo plugin.
Now you need to tell the location for the settings file you just created. This is also done there in nuxt.config.js.
The settings can be specified anywhere in the file, but I usually specify them at the very end.
...
apollo: {
clientConfigs: {
default: '~/graphql'
}
},
...
In the file ./graphql/index.js you might have noticed the env variable nuxtApiUrl, which we cast to set the API link. Let's add it.
Open nuxt.config.js again, scroll to the bottom and add a new variable there in the env block.
...
env: {
nuxtApiUrl: process.env.NUXT_API_URL
// the variable from the .env file, which must be in the root of the project
},
...
This concludes the basic setup of @nuxtjs/apollo.
3. Next, configure @vue/apollo-composable
This package will be embedded in Nuxt as a plugin, so create a plugins folder in the root with the apollo-client.js file.
In the apollo-client.js file, import @vue/apollo-composable, which will connect to @nuxtjs/apollo.
import { provide, onGlobalSetup, defineNuxtPlugin } from '@nuxtjs/composition-api';
import { DefaultApolloClient } from '@vue/apollo-composable/dist';
export default defineNuxtPlugin(({ app }) => {
onGlobalSetup(() => {
provide(DefaultApolloClient, app.apolloProvider?.defaultClient);
});
});
Let's install the plugin in the nuxt settings.
...
plugins: [
'~/plugins/apollo-client.js'
],
...
And the last step is to import the plugin into the build block, so that it is available to all scripts. This is done in the same file nuxt.config.js
...
build: {
transpile: [
'@vue/apollo-composable'
]
},
...
This completes the client setup.
How to use ArolloClient on a client
Now a few words about how to use Apollo on the client.
Important: all requests to the server through AroloClient should be made on pages, in the folder ./pages. This will allow you to make asynchronous requests on the nuxt-server side and render pages with already prepared data. Asynchronous requests do not work in components.
So, to use the @vue/apollo-composable plugin, you have to import it. Then just pull out the necessary methods as in the example below
<script>
import {
defineComponent
} from '@nuxtjs/composition-api';
import { useQuery, useResult } from '@vue/apollo-composable/dist';
import { GET_USERS } from '@/graphql/types';
export default defineComponent({
setup() {
// ------- Get all users -------- //
const { result, loading, error } = useQuery(GET_USERS);
// -------- Computeds -------- //
const users = useResult(result, null, data => data.users);
return {
users,
loading,
error
};
}
})
</script>
I will not tell you how to work with this library, today is not about that. But I will leave a link to the documentation, of course https://v4.apollo.vuejs.org/guide-composable/query.html#graphql-document
The only thing I couldn't find in the documentation is how to useLazyQuery method. It's designed for queries that need to be executed by click or any other event.
After digging in the code, it turns out that the method useLazyQuery returns an additional function load, which should be used to make a request in the right place.
...
const { result, load } = useLazyQuery(GET_ALL_USERS);
...
function onClick() { load(); }
Conclusion
That's about it. We have successfully configured everything we wanted, now all that's left is the programming and layout. How to use what we've got is a topic for another article.
I hope you will find this tutorial useful and save your valuable time. Also, don't forget to poke around in the finished project to get a better grasp of the material.
Thank you.
Previously published at maddevs.io/blog.
Top comments (0)