DEV Community

Cover image for How to configure Apollo GraphQL in Nuxt application
Mad Devs for Mad Devs

Posted on • Updated on

How to configure Apollo GraphQL in Nuxt application

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:

Open the terminal and install the packages

npm i -S apollo-server-express @nuxtjs/composition-api 
@nuxtjs/apollo @vue/apollo-composable
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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' }],
...
Enter fullscreen mode Exit fullscreen mode

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'
],
...
Enter fullscreen mode Exit fullscreen mode

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'
],
...
Enter fullscreen mode Exit fullscreen mode

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
  }
}
Enter fullscreen mode Exit fullscreen mode

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'
  }
},
...
Enter fullscreen mode Exit fullscreen mode

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
},
...
Enter fullscreen mode Exit fullscreen mode

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);
  });
});
Enter fullscreen mode Exit fullscreen mode

Let's install the plugin in the nuxt settings.

...
plugins: [
  '~/plugins/apollo-client.js'
],
...
Enter fullscreen mode Exit fullscreen mode

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'
  ]
},
...
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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(); }
Enter fullscreen mode Exit fullscreen mode

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)