В предыдущей статье мы сгенерировали типобезопасные GraphQL-композиции из файлов .graphql
для использования в нашем коде фронтенда VueJS. Под капотом сгенерированные функции полагаются на клиент @urql/vue
, который необходимо сначала настроить, прежде чем пытаться получить доступ к нашим операциям GraphQL.
Настройка @urql/vue с помощью плагина Nuxt3
Для начала мы можем предоставить базовый клиент @urql/vue
с плагином в plugins/urql.ts
:
import urql from "@urql/vue";
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
export default defineNuxtPlugin((nuxtApp) => {
const { graphqlApiURL } = useRuntimeConfig();
nuxtApp.vueApp.use(urql, {
url: graphqlApiURL,
});
});
Мы предоставляем graphqlApiURL
в качестве публичной конфигурации времени выполнения в nuxt.config.ts
:
publicRuntimeConfig: {
graphqlApiURL: process.env.GRAPHQL_API_URL || "http://localhost:3000/api/graphql",
}
Мы могли бы попытаться определить URL API на основе опций Nuxt во время сборки или выполнения, но гораздо проще определить его явно.
Настройка обмена SSR
При выполнении запросов в странице и/или компоненте(ах), полученные результаты могут быть объединены и сериализованы в полезной нагрузке страницы, отправленной сервером, а затем повторно обработаны клиентом при рендеринге.
Для этого нам нужно переопределить стандартные обмены urql
, добавив настроенный SSR-обмен в нужный индекс массива.
Соответствующий код для настройки выглядит следующим образом:
// ...
import urql, { cacheExchange, dedupExchange, fetchExchange, ssrExchange } from "@urql/vue";
// ...
// Create SSR exchange
const ssr = ssrExchange({
isClient: process.client,
});
// Extract SSR payload once app is rendered on the server
if (process.server) {
nuxtApp.hook("app:rendered", () => {
nuxtApp.payload?.data && (nuxtApp.payload.data.urql = ssr.extractData());
});
}
// Restore SSR payload once app is created on the client
if (process.client) {
nuxtApp.hook("app:created", () => {
nuxtApp.payload?.data && ssr.restoreData(nuxtApp.payload.data.urql);
});
}
// Custom exchanges
const exchanges = [dedupExchange, cacheExchange, ssr, fetchExchange];
// ...
Массив exchanges
затем передается в опции urql
для переопределения стандартных.
Я не уверен на 100% в приведенном выше коде обработки полезной нагрузки сервера/клиента, но он работает (возможно, есть какие-то помощники Nuxt для достижения этого более простым способом).
Бонус: Настройка обмена devtools
Может быть полезно отлаживать urql
с помощью его официального devtools. Давайте добавим его в наши зависимости:
yarn add -D @urql/devtools
Затем мы можем добавить его к нашим пользовательским обменам в plugins/urql.ts
:
import { devtoolsExchange } from "@urql/devtools";
// ...
// Devtools exchange
if (nuxtApp._legacyContext?.isDev) {
exchanges.unshift(devtoolsExchange);
}
// ...
И вуаля, наше приложение теперь должно отображать отладочные события в панели devtools, при условии, что расширение правильно установлено в вашем браузере.
Использование сгенерированных операций
Поскольку наши сгенерированные операции могут быть автоматически импортированы (см. предыдущую статью), выполнить наш запрос { hello }
очень просто:
<script setup lang="ts">
const { data } = await useHelloQuery();
</script>
<template>
<div id="front-page" class="prose">
<h1>{{ data?.hello || "Nuxt3 ❤️ GraphQL" }}</h1>
</div>
</template>
Насколько это удивительно? Благодаря синтаксису <script setup>
и автоимпортированию, одной строки TypeScript достаточно, чтобы выполнить нашу сгенерированную операцию запроса и получить доступ к результату с полной безопасностью типов!
Что насчет мутаций (и подписок)?
Использование сгенерированных операций мутации не сильно отличается от использования запросов, главное отличие в том, что мутация не выполняется автоматически. Вместо этого мы должны использовать метод executeMutation
на объекте результата, возвращенном из нашей сгенерированной композиции, т.е. useSomeMutation
.
Что касается подписок, то для их использования нам потребуется настроить какой-то вид транспорта. Этому будет посвящена следующая статья в этом увлекательном цикле!
За дополнительной информацией обращайтесь к документации @urql/vue
по мутациям и подпискам.