Как настроить Apollo GraphQL в Nuxt приложении
Создание полноценного приложения при помощи Nuxt и Apollo GraphQL
Введение
Друзья, доброго времени суток!
Сегодня хочу показать вам как настроить Apollo GraphQl в Nuxt приложении, где nuxt возьмёт на себя как клиентскую часть так и серверную. В итоге, у нас получится полноценная структура для разработки полнофункционального приложения.
Я подготовил готовый пример, который можно поднять и щупать параллельно с чтением. В нём вы можете найти настройки сервера, настройки клиента и несколько примеров использования Apollo.
Цель этой статьи — дать краткую инструкцию, по быстрой настройке Apollo GraphQl в Nuxt приложении.
Буду максимально краток, всё строго и по-делу.
Начнём!
Установка пакетов
Нам понадобится следующий список пакетов:
- apollo-server-express — пакет, который обеспечит поддержку apollo на сервере.
- @nuxtjs/composition-api — для поддержи 3ей версии Vue в Nuxt.
- @nuxtjs/apollo — обёртка вокруг плагина vue-apollo, для работы с Nuxt.
- @vue/apollo-composable — добавляет вспомогательные функции Apollo GraphQL для Nuxt Composition API.
Откроем терминал и установим пакеты
npm i -S apollo-server-express @nuxtjs/composition-api @nuxtjs/apollo @vue/apollo-composable
Конфигурация сервера
Если вы вдруг не знали, nuxt для рендера страниц использует express.js сервер. Это необходимо для того, чтобы за ранее готовить html файлы, тем самым решая проблемы с SEO. Так работает режим SSR в nuxt.
Но nuxt сервер можно использовать не только для рендера html файлов, но так же и в своих целях, например, для создания простого API. Чем сегодня мы и займемся.
Давайте начнём с создания структуры для сервера.
В корне проекта создадим папку server, в которую добавим файл index.js. Этот файл будет точкой входа для сервера.
Добавим в него вот такой код
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;
В коде выше, мы импортировали apollo-server-express, с помощью которого у нас появляется возможность работать с Apollo GraphQL на сервере. Обязательно добавим корсы, чтобы защититься от посторонних доменных запросов. Сконфигурируем это всё и вернём экземпляр, который будет запущен nuxt сервером.
Теперь, чтобы указать nuxt какой файл запустить в качестве сервера, перейдем в файл nuxt.config.js и добавим туда новую конфигурацию
...
/*
** Server middlewares
*/
serverMiddleware: [{ path: '/', handler: '~/server/index.js' }],
...
Опция serverMiddleware позволяет регистрировать дополнительные маршруты без необходимости использования внешнего сервера. Проще говоря, эта опция как раз таки и даёт нам возможность подключаться к серверу nuxt.
На этом настройка сервера завершена.
Конфигурация клиента
- Начнём с настройки @nuxtjs/composition-api.
Для этого перейдём в файл nuxt.config.js, который располагается в корне проекте, найдём блок modules: [] и там подключим Nuxt Composition Api
...
modules: [
'@nuxtjs/composition-api/module'
],
...
Таким образом, Composition Api будет доступен глобально во всех компонентах.
2. Следующий на очереди @nuxtjs/apollo
С ним та же песня, его так же нужно добавить в modules
...
modules: [
'@nuxtjs/composition-api/module',
'@nuxtjs/apollo'
],
...
После этого добавим для него настройки, где мы укажем ссылку на API, настройки кеширования, хедеры и прочие штуки.
Создадим в корне проекта новую папку под названием graphql. В ней будет храниться всё, что относится к graphql.
В этой же папке создадим файл index.js, точку входа, от куда плагин @nuxtjs/apollo будет тянуть для себя настройки.
В файл добавим следующий код
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
}
}
Пакеты, которые подключаются в начале файла, были установлены вместе с плагином @nuxtjs/apollo.
Теперь нужно сообщить местоположение для только что созданного файла настроек. Это делается там же в nuxt.config.js.
Настройки можно указать в любом месте файла, но я обычно указываю их в самом конце.
...
apollo: {
clientConfigs: {
default: '~/graphql'
}
},
...
В файле ./graphql/index.js вы могли заметить env переменную nuxtApiUrl, которую мы прокидываем для установки ссылки на API. Давайте добавим её.
Снова откроем файл nuxt.config.js, прокрутим в самый низ и там в блоке env добавим новую переменную.
...
env: {
nuxtApiUrl: process.env.NUXT_API_URL // переменная из .env файла, который должен располагаться в корне проекта
},
...
На этом базовую настройку @nuxtjs/apollo мы закончили.
3. Далее настроим @vue/apollo-composable
Этот пакет будет встраиваться в Nuxt как плагин, поэтому создадим в корне папку plugins в файлом apollo-client.js.
В файле apollo-client.js импортируем @vue/apollo-composable, который подключится к @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);
});
});
Установим плагин в настройках nuxt.
...
plugins: [
'~/plugins/apollo-client.js'
],
...
Ну и последним шагом нужно импортировать плагин в блок build, чтобы он был доступен для всех скриптов. Это делается всё в том же файле nuxt.config.js
...
build: {
transpile: [
'@vue/apollo-composable'
]
},
...
На этом настройка клиента завершена.
Как использовать АpolloClient на клиенте
Теперь пару слово о том, как пользоваться Apollo на клиенте.
Важно: выполнять все запросы на сервер через АpolloClient, нужно на страницах, в папке ./pages. Это позволит вам делать асинхронные запросы на стороне nuxt-сервера и рендерить страницы с уже готовыми данными. В компонентах асинхронные запросы не работают.
Итак, чтобы использовать плагин @vue/apollo-composable, его необходимо импортировать. Потом просто вытаскиваем нужные методы как в примере ниже
<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>
Рассказывать про то, как работать с этой библиотекой я не буду, сегодня речь не об этом. Но ссылку на документацию конечно же оставлю https://v4.apollo.vuejs.org/guide-composable/query.html#graphql-document
Единственное, в документации не нашёл как использовать метод useLazyQuery. Он предназначен для запросов, которые требуется выполнять по клику или по любому, другому событию.
Покопавшись в коде, оказалось, что метод useLazyQuery возвращает дополнительную функцию load, с помощью который и должны делать запрос в нужном месте.
...
const { result, load } = useLazyQuery(GET_ALL_USERS);...
function onClick() { load(); }
Заключение
Собственно и всё. Мы успешно настроили всё, что хотели, остаётся только программировать и верстать. Как пользоваться тем, что у нас получилось это уже тема другой статьи.
Надеюсь, эта инструкция окажется полезной для вас и сохранит ваше драгоценное время. Так же не забудьте поковыряться в готовом проекте, чтобы лучше усвоить материал.
Спасибо.