LoginSignup
4
4

More than 3 years have passed since last update.

【Nuxt.js】ポケモンで学ぶGraphQL

Last updated at Posted at 2021-03-17

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コンソールにコピペして[▶]を押すと・・・

demo

このような画面になったでしょうか。

右側にはクエリに対するレスポンスが表示され、ピカチュウの名前だけ取得できていることがわかります。



では、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の定義を記述します。
手動で作成しましょう。

nuxt.config.js
modules: ['@nuxtjs/apollo'],
  apollo: {
    clientConfigs: {
      default: '~/plugins/apollo-auth.js',
    },
  },

// コピペ用
touch plugins/apollo-auth.js

~/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

~/apollo/queries/getPokemons.gql
query GetPokes{
  pokemons(first: 151){
    number
    image
  }
}

queryの隣のGetPokesとは何でしょうか?
クエリにはOperation typeOperation nameを指定できます。

  • Operation type
    • 実行する操作の種類を示す(query、mutation、subscription)
    • 基本必須です。
  • Operation name
    • そのクエリが実行する操作を明示する名前
    • 任意ですが、デバッグやサーバーサイドでのログ収集に便利な為使用が推奨されています。

今回のクエリはpokemonからpokemonsに変わっています。
パラメータもnameからfirstに変わり数値を受け取るようになっています。

どのクエリが使用できるかはGraphiQLの画面右側のDoc(Documentation Explorer)から確認できます。

スクリーンショット 2021-03-17 4.56.00.png

スクリーンショット 2021-03-17 4.57.04.png

スクリーンショット 2021-03-17 5.12.18.png


このようなフィールドと、対応した型を入れてくださいね〜といった仕様の記述のことをスキーマと言います。

スキーマ
GraphQL APIの仕様の定義
この定義に従ってクエリを実行することでデータを取得できる


では、レスポンスをテンプレートに表示させましょう。

index.js
<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を指定しました。

表示を確認します。

スクリーンショット 2021-03-17 5.54.20.png

ポケモン達が表示されています!

みんなもポケモンゲットだぜ!!!

おまけ

変数を使用する

apolloオブジェクト内のvariablesプロパティでクエリに変数を渡せます。

apollo: {
    pokemons: {
      query: getPokes,
      variables: {
        num: 1,
      },
    },
  },
~/apollo/queries/getPokemons.gql
query GetPokes($num: Int!){
  pokemons(first: $num){
    number
    image
  }
}

変数をリアクティブにする

variablesを関数にすることでリアクティブになる

apollo: {
    pokemons: {
      query: getPokes,
      variables() {
        return {
          num: this.num,
        }
      },
    },
  },

demo


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>

demo

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4