Nuxt で GraphQL のクエリを送信する方法
こんにちは。 SAW です。
最近、自分の声の通りにくさに少し悩んでいます。
時々、店員さんに聞き取られないことがあるので、改善したいなと思っています。
フロントエンドを Nuxt で開発する際に、 REST API で通信する場合は、 $fetch()
や useFetch()
などを利用します。
しかし、 GraphQL のクエリを送信する場合は、 GraphQL のクライアントライブラリを利用する方が便利です。
本記事では、 Nuxt で GraphQL のクエリを送信する方法を紹介します。
また、本記事では Nuxt 3 系の環境を想定しています。
この記事は 2024/2/29 に開催された Reboot v-kansai Meetup #15 で発表した内容を記事に書き起こしたものです。
資料を以下に貼ってありますので、ご興味のある方はご一読いただけると幸いです。
対象読者
本記事で想定する読者層は次の通りです。
- Nuxt について基本的な知識を有している
- GraphQL について基本的な知識を有している
Nuxt から GraphQL のクエリを送信する方法
Nuxt から GraphQL のクエリを送信する方法として、以下の手段が考えられます。
- GraphQL のクライアントライブラリを利用する
- HTTP 通信ライブラリでクエリを request body につけて送信する
基本的には GraphQL のクライアントライブラリを利用した方が、開発がスムーズに進みます。
そこで、 Nuxt 向けの GraphQL のクライアントライブラリを探します。
Nuxt 用の GraphQL クライアントライブラリは、 Nuxt の公式ページの Nuxt Modules から検索すると便利です。
Nuxt 用の GraphQL クライアント
Nuxt Modules で検索すると、以下のライブラリが見つかりました。
-
Nuxt GraphQL Client
- Nuxt 用の graphql-request + GraphQL Code Generator の最小構成
-
Nuxt Apollo
- Nuxt 用の Apollo Client
-
graphql-request
- GraphQL クライアントとしての最小限の機能をサポートするモジュール
上記のライブラリのうち、 Nuxt GraphQL Client について以降の章で紹介します。
Nuxt GraphQL Client の特徴
Nuxt GraphQL Client の大きな特徴は以下の 3 つが挙げられます。
- GraphQL のクエリを別ファイルに記述
- ほぼ設定なしで利用可能
- TypeScript 完全サポート
特に一番最初の GraphQL のクエリを別ファイルに記述できる 点が個人的推しポイントです。
GraphQL のクエリを別ファイルに記述
Nuxt GraphQL Client の大きな特徴として、 GraphQL のクエリを別ファイルに記述できます。
クエリは .gql
または .graphql
の拡張子のファイルに記述します。
記載した GraphQL を Vue から利用するには、 useAsyncGql()
を呼び出します。
送信対象のクエリを指定するには、引数のオプションの operation
から指定します。
useAsyncGql()
は Nuxt の useAsyncData()
と同様の構造をしたオブジェクトを返します。
data
プロパティにレスポンスのデータが、 pending
にはデータを取得中かの boolean が reactive な値 として格納されています。
以下に簡単なコード例を記載します。
query getCountries {
countries {
code
name
}
}
<script setup lang="ts">
const { data, pending } = await useAsyncGql({
operation: 'getCountries', // GraphQL のクエリ名を指定
});
</script>
<template>
<p v-if="pending">Loading...</p>
<div v-else>
<ul>
<li
v-for="country in data.countries"
:key="country.code"
>
{{ country.name }}
</li>
</ul>
</div>
</template>
上記のコード例では、 GraphQL のクエリ getCountries
を useAsyncGql()
の operation
として指定しています。
getCountries
のクエリを送信すると、以下のようなデータを取得できます。
{
"data": {
"countries": [
{
"code": "ja",
"name": "Japan"
}
]
}
}
useAsyncGql()
の返り値の pending
を利用して読み込み中なら Loading...
と表示し、データの取得が完了したら取得したデータを data.countries
から取り出して表示しています。
ほぼ設定なしで利用可能
Nuxt GraphQL Client は以下の 2 点を設定すれば、必要最小限の利用が可能です。
-
nuxt.config.ts
のmodules
プロパティに追加 - データ取得先の GraphQL サーバーの URL を
.env
へ追加
nuxt.config.ts
の設定の追加
nuxt.config.ts
の modules
プロパティに 'nuxt-graphql-client'
を追加します。
export default defineNuxtConfig({
modules: ['nuxt-graphql-client'],
});
.env
へ環境変数の追加
.env
に GQL_HOST
という環境変数を追加し、データ取得先の GraphQL サーバーの URL を設定します。
GQL_HOST="https://localhost/graphql"
TypeScript 完全サポート
GraphQL のクエリ情報をもとに、 返却型の型情報 が自動生成されます。
VSCode などのエディタで useAsyncGql()
が返却するオブジェクトの data
プロパティを確認すると、下図のように type hinting が表示されます。
GraphQL のクエリに基づいて useAsyncGql()
の返却値に型情報が VSCode 上に表示される例
型情報が生成されると、返却型だけでなく、 useAsyncGql()
のオプションの operation
に指定するクエリ名も 補完 で候補が表示されるようになります。
注意点として、型情報を取得するには npm dev
などのコマンドを実行 する必要があります。
これは Nuxt GraphQL Client が GraphQL サーバーからスキーマ情報を取得し、さらに記述されたクエリに基づいて型情報を生成していると考えられます。
(内部の詳細な動作までは確認できていないので、あくまで推測です。)
useAsyncGql()
の引数オプション
useAsyncGql()
の引数にはクエリを指定する operation
オプション以外にもいくつかオプションが存在します。
主要なオプションとして、以下の 2 つを紹介します。
-
variables
: クエリ変数を指定 -
options.transform
: クエリから取得したデータを変形する関数を指定
variables
variables
には、クエリ変数を指定します。
operation
と同様に、 type hinting や補完が表示されます。
variables
の型情報が VSCode 上に補完で表示される例
options.transform
useAsyncData()
の transform
オプションと同様に、レスポンスのデータを変形する関数を指定できます。
特に TypeScript を利用している場合は、フロントエンド側の型に合うようにデータ型を変形させる際に便利です。
interface Country {
id: string;
name: string;
}
// data は Ref<Country[]> 型になる
const { data } = await useAsyncGql({
operation: 'getCountries',
options: {
transform(response): Country[] {
// getCountries のレスポンスを Country[] に変換
return response.countries.map((x) => ({
id: x.code,
name: x.name,
}));
},
},
});
困っている点
これまで Nuxt GraphQL Client の基本的な使い方を説明しました。
GraphQL のクエリを Vue のコードから分割できたり、 TypeScript に対応していたりといったメリットがあることを紹介しました。
一方で、下記のような困っている点も存在します。
- 公式ドキュメントがやや読みづらい
- ファイルのアップロードに非対応っぽい
特に、ファイルのアップロードが非対応っぽいのは、代替手段を考えないといけないので、個人的には結構悩みの種になっています。
公式ドキュメントの読みづらさ
公式ドキュメントは存在しているのですが、使い方の詳細を理解するには少し読みづらく感じました。
特に使い慣れていない最初の段階では、ライブラリの使い方を把握するのに少し苦労するかもしれません。
また、 Stack Overflow などの公式ドキュメント以外でも情報が見つかりづらいため、情報収集は少し苦労します。
ファイルのアップロードに非対応っぽい
このライブラリではファイルのアップロードには対応していないのか、ドキュメントや GitHub の Discussions を探ってみても方法が見つかりませんでした。
Nuxt GraphQL Client は graphql-request に依存していますが、どうやらファイルを扱う機能を削除したようです。
かわりに middleware を利用することでファイルアップロードをサポートする方法が提案されています。
ただ、 Nuxt GraphQL Client で middleware を追加する方法は見つからなかったため、どちらにしてもファイルのアップロードは現在のところは非対応と思われます。
まとめ
本記事のまとめは次の通りです。
- Nuxt で GraphQL のクエリを送信する方法を紹介
- Nuxt GraphQL Client の基本的な使い方を紹介
他の GraphQL クライアントのライブラリも触ってみて、良し悪しを比較してみたいなと思いました。
参考文献
Discussion