GraphQL Pokemonを使ってGraphQLを学んでいきます。
GraphQLって?
GraphQLはFacebookがリリースした、Web API用のクエリ言語です。
REST APIと比べ
・エンドポイント(/user、/post/:id、等)が一つで済む
・クライアント側で取得するデータを選択できる
・リクエスト・レスポンスの型の定義ができる
などのメリットがある。
試しにGraphQLを使ってみよう
GraphQL Pokemonコンソールからデータを取得するためにクエリを送信します。
GraphQLには三種類のクエリが存在する
・query(データ取得) GET
・mutation(データ更新) POST/PUT/DELETE...etc
・subscription(サーバーサイドからのイベント通知) Websocket
例えばピカチュウの名前を取得するならqueryを使用します。
query {
pokemon(name: "pikachu") {
name
}
}
このクエリをGraphQL Pokemonコンソールにコピペして[▶]を押すと・・・
このような画面になったでしょうか。
右側にはクエリに対するレスポンスが表示され、ピカチュウの名前だけ取得できていることがわかります。
では、GraphQLをプロジェクトに組み込んでみます。
Nuxtプロジェクト作成
個人的な理由でNuxt.jsでGraphQLを使っていきます。
$ npx create-nuxt-app poke-gql
create-nuxt-app v3.4.0
✨ Generating Nuxt.js project in poke-gql
? Project name: poke-gql
? Programming language: JavaScript
? Package manager: Yarn
? UI framework: None
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert se
lection)
? Linting tools: ESLint, Prettier
? Testing framework: None
? Rendering mode: Single Page App
? Deployment target: Server (Node.js hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert
selection)
? Continuous integration: None
? Version control system: Git
Apollo Client
クライアントサイドでGraphQLを使用するためにApollo Clientというライブラリが必要です。
Nuxt.jsにはApollo Clientをもっと使いやすくした@nuxtjs/apolloというモジュールがあるのでこちらをインストールします。
$ yarn add @nuxtjs/apollo
イントスールが終わったらnuxt.config.jsに設定を追加します。
"~/plugins/apollo-auth.js"
にclientOptionsの定義を記述します。
手動で作成しましょう。
modules: ['@nuxtjs/apollo'],
apollo: {
clientConfigs: {
default: '~/plugins/apollo-auth.js',
},
},
// コピペ用
touch plugins/apollo-auth.js
export default () => {
return {
httpEndpoint: 'https://graphql-pokemon2.vercel.app/',
}
}
httpEndpoint: 'https://graphql-pokemon2.vercel.app/'
このURLはGraphQL PokemonコンソールのURLです。
クエリを記述する
クエリは~/apollo/queries/getPokemons.gql
内に記述します。
mkdir apollo
mkdir apollo/queries
touch apollo/queries/getPokemons.gql
query GetPokes{
pokemons(first: 151){
number
image
}
}
query
の隣のGetPokes
とは何でしょうか?
クエリにはOperation typeとOperation nameを指定できます。
- Operation type
- 実行する操作の種類を示す(query、mutation、subscription)
- 基本必須です。
- Operation name
- そのクエリが実行する操作を明示する名前
- 任意ですが、デバッグやサーバーサイドでのログ収集に便利な為使用が推奨されています。
今回のクエリはpokemon
からpokemons
に変わっています。
パラメータもname
からfirst
に変わり数値を受け取るようになっています。
どのクエリが使用できるかはGraphiQLの画面右側の**Doc(Documentation Explorer)**から確認できます。
このようなフィールドと、対応した型を入れてくださいね〜といった仕様の記述のことをスキーマと言います。
スキーマ
GraphQL APIの仕様の定義
この定義に従ってクエリを実行することでデータを取得できる
では、レスポンスをテンプレートに表示させましょう。
<template>
<div>
<div v-for="poke in pokemons" :key="poke.id">
{{ poke.number }}
<img width="100" height="100" :src="poke.image" />
</div>
</div>
</template>
<script>
import getPokes from '~/apollo/queries/getPokemons.gql' // ・・・①
export default {
data() {
return {
pokemons: [], // ・・・③
}
},
apollo: {
pokemons: {
query: getPokes, // ・・・②
},
},
}
</script>
①・・・記述したクエリをインポートします
②・・・apolloオブジェクトを追加し、その中にプロパティを定義
③・・・dataプロパティに初期値をセットします。初期値の定義はクエリのフィールドと一致している必要があります。
さて、今回のクエリは指定した数のポケモンと、その数分のポケモンのデータを取得するものです。
データにはnumberとimageを指定しました。
表示を確認します。
ポケモン達が表示されています!
みんなもポケモンゲットだぜ!!!
おまけ
変数を使用する
apolloオブジェクト内のvariablesプロパティでクエリに変数を渡せます。
apollo: {
pokemons: {
query: getPokes,
variables: {
num: 1,
},
},
},
query GetPokes($num: Int!){
pokemons(first: $num){
number
image
}
}
変数をリアクティブにする
variablesを関数にすることでリアクティブになる
apollo: {
pokemons: {
query: getPokes,
variables() {
return {
num: this.num,
}
},
},
},
this.$apollo
今までapolloオブジェクトでapollo-clientインスタンスにアクセスしていました。
この方法をSmart Queryと言います。
今度はthis.$apolloを使用してapollo-clientインスタンスにアクセスしてみます。
async created() {
this.pokemons = await this.$apollo.query({
query: getPokes2,
variables: {
num: this.num,
},
})
},
this.$apollo.query
はPromiseを返します
ローディング
this.$apollo.loading
でローディングを検知できます。
<div v-if="$apollo.loading">ちょっと まってね</div>