Join us at Jamstack Conf, October 6-7. Register for free!

By Sarah Drasner in Guides & Tutorials

Hasura と Nuxt で GraphQL を作成

このページの利用可能言語 English, 日本語.

私見ですが、GraphQL で Jamstack アプリを作成する最も簡単な方法の 1 つは、Hasura と Nuxt の組み合わせです。開発者としてこれほどワクワクする経験はありません。

開発中のアプリ:
hasura-nuxt-demo.netlify.app

リポジトリ:
github.com/sdras/favegame

わかりやすくするために基本機能に絞って取り上げますが、ここからさらに豊かな体験を簡単に積み重ねることができます。では、始めましょう!

セットアップ

まず、無料の Hasura アカウントを作成します。このとき、独自の Postgres データベースを使用するか(例えるなら BYOP)、新規または既存の Heroku アカウントにリンクして新しいデータベースを作成するか、選択を求められます。自分に適したオプションを選択してください(私の場合、自分の Heroku アカウントにリンクしました)。

そこから、新しいプロジェクトを作成します。このプロジェクトでは、テーブルを作成し、必要なフィールドを追加します。最初の表は ‘users’ です。必要なフィールドは、’Integer’ 型(自動増分)の ‘id’、’Text’ 型(’String’ の別名)の ‘name’、および、もう一つの ‘Text’ 型の ‘profileImg’ です。

そこでは、[Insert Row](行の挿入)タブに何行かのダミーデータを挿入します。[Browse Rows](行の参照)タブに切り替えると、ダミーデータが入力されていることがわかります。

次に、’favoriteGames’ という別のテーブルを作成して、同じ操作を実行します。今度は、同じ id と name を使用し、さらに ‘rating’(integer 型)と ‘image’(Text 型)を追加します。

次に、一番上の[GRAPHIQL]タブに移動し、最初のクエリをテストして、結果を確認する必要があります。

query getGames {
  favoriteGames {
    id
    image
    name
    rating
  }
}

戻り値:

{
  "data": {
    "favoriteGames": [
      {
        "id": 1,
        "image": "mafia.jpg",
        "name": "Mafia",
        "rating": 5
      },
      {
        "id": 2,
        "image": "gta.jpg",
        "name": "Grand Theft Auto",
        "rating": 4
      },
      {
        "id": 5,
        "image": "jumanji.jpg",
        "name": "Jumanji",
        "rating": 3
      },
      {
        "id": 4,
        "image": "blackjack.jpg",
        "name": "Black Jack",
        "rating": 5
      },
      {
        "id": 3,
        "image": "fortnite.jpg",
        "name": "Fortnite",
        "rating": 5
      },
      {
        "id": 6,
        "image": "minecraft.jpg",
        "name": "Minecraft",
        "rating": 4
      }
    ]
  }
}

よくできました!しかし、私たちが本当に求めているものは、すべてのゲームのリストと、その各ゲームに関連付けられた該当アクティブユーザーのリストです。2 つのテーブル間の関連付けを作成するために、リレーションシップを作成する必要があります。

リレーションシップ

‘users’ テーブルに戻り、’Modify’(変更)タブをクリックしてみましょう。ここで、フィールドをもう一つ追加で作成します。名前は ‘gameId’ とします。これで、’favoriteGames’ テーブルから関連 ID を選択できるようになります。その後、’Browse Rows’(行の参照)タブに戻り、ゲームの ID 番号をいくつか追加しましょう。

次に、favoriteGames に戻り、[Relationships](リレーションシップ)タブをクリックします。テーブルで、[Array Relationship](配列リレーションシップ)を指定し、「gameUser」という名前を付け、users テーブルを参照します。

このテーブルの ID は、先ほど他の users テーブルで作成した gameId とリレーションシップを持ちます。

保存すると、このタブのテーブルに配列リレーションシップが反映されます。

users . gameId → favoriteGames . id

ここで、一番上の[GRAPHIQL]タブに戻り、このリレーションシップを含む新しいクエリを入力できます。

query getGames {
  favoriteGames {
    id
    image
    name
    rating
    gameUser {
      id
      name
      profileImg
    }
  }
}

すばらしい!これで、最初のデータセットとリレーションシップが設定され、アプリケーションで使用する準備ができました。

Nuxt アプリの構築

それでは、Nuxt アプリケーションを構築しましょう。このチュートリアルは、Nuxt の基本的な知識を備えていることを前提としていますが、Nuxt の使い方がわからない場合は、Frontend Masters のコースのいくつかでセットアップの方法を学習できます。

アプリの作成に入ります。

yarn create nuxt-app

プロンプトに従ってください。最後のプロンプトで、デプロイターゲットとして ‘static’(Jamstack アプリ)を選択します。次に、必要なパッケージを追加します。

yarn add @nuxtjs/apollo graphql-tag

Nuxt の構成

ここからは、nuxt.config.js を開き、モジュールを使用することを認識させることができます。

modules: ["@nuxtjs/apollo"],

また、Apollo 用のセクションも追加できます。

 apollo: {
   clientConfigs: {
     default: {
       httpEndpoint: process.env.HASURA_ENDPOINT
     }
   }
 },

ここで、環境変数を使用していることがわかると思います。プロジェクトのベースルートに ‘.env’ ファイルを作成し、次のエンドポイントを挿入します。

HASURA_ENDPOINT=https://yourendpointhere.hasura.app/v1/graphql

[GRAPHIQL]タブの上部にエンドポイントがあります(GraphQL エンドポイントとなります)。

ストアへの追加

このようなアプリケーションでは、Vuex ストアからデータを比較的簡単に取得できる場合は、そうするとよいでしょう。それにより、データソースを一元化できます。また、どのデータがどのページに取り込まれるかについて、有限的な制御があるとよいでしょう。構築したアプリは Vuex ストアを使用していますが、ここでは 2 通りの方法を紹介します。

store/index.js で、

まず gql をインストールする必要があります。

import gql from "graphql-tag";

次に、favoriteGames を保存するステートが必要です。

export const state = () => ({
 favoriteGames: \[]
});

[ACTIONS](アクション)で、このアプリを使用して Apollo を呼び出し、アクセスします。gql を使用してクエリを作成し、次にミューテーションをコミットします。

export const actions = {
 async callApollo({ commit }) {
   let response = await this.app.apolloProvider.defaultClient.query({
     query: gql`query GetGames {
         favoriteGames {
           id
           image
           name
           rating
           gameUser {
             id
             name
             profileImg
           }
         }
       }`
   });

   await commit("updateFavoriteGames", response.data.favoriteGames);
 }
};

次に、このデータをステートに保存するミューテーションを作成します。

export const mutations = {
 updateFavoriteGames: (state, data) => {
   state.favoriteGames = data;
 }
};

最後に、このアクションをディスパッチする必要があります。ファイル名のサフィックスとして ‘.server.js’ を使用して、サーバーから呼び出すプラグインを作成します。

plugins/getGames.server.js

export default async ({ store }) => {
 await store.dispatch("callApollo");
};

このプラグインを ‘nuxt.config.js’ に登録すると、サイトをビルドするたびに、Vuex ストアにすべてのデータが収集されます!

plugins: ['~/plugins/getGames.server.js'],

[Vuex]タブの devtools を見ると、次のようなデータが表示されます。

上出来です!Hasura からのデータとアプリケーションとのリレーションシップが作成されました。

これで、データを通常どおりビューに追加できます。pages/index.vUE では、次のようになります。

<template>
 <div class="container">
   <h1>Favorite Games</h1>

   <main class="game-container">
     <section v-for="game in favoriteGames" :key="game.id">
       <AppGame :game="game" />
     </section>
   </main>
 </div>
</template>

<script>
import { mapState } from "vuex";
import AppGame from "@/components/AppGame.vue";

export default {
 components: {
   AppGame
 },
 computed: {
   ...mapState(["favoriteGames"])
 }
};
</script>

いい感じです!

もう一つの方法:Per-Page

import gql from "graphql-tag";

export default {
 apollo: {
   favoriteGames: {
     query: gql`query MyQuery {
         favoriteGames {
           id
           image
           name
           rating
           gameUser {
             id
             name
             profileImg
           }
         }
       }`,
     update(data) {
       return data.favoriteGames;
     }
   }
 },
}
</script>

実装についてはこちらで確認できます。

アプリを Netlify にデプロイする

Nuxt アプリケーションをデプロイするには、Netlify にログインし、リポジトリを検索して接続し、次のオプションを選択することで、GitHub または GitLab リポジトリをプロジェクトにフックします。

ビルドコマンド:
‘yarn generate’

公開ディレクトリ:
‘dist’

最後に、[Settings](設定)タブに移動し、[Environment](環境)までスクロールダウンして、[Environment Variables](環境変数)セクションで、ローカルの ‘.env’ ファイルに追加したのと同じエンドポイントを追加します。

できました!アプリがインターネットに公開されました。

最後に、更新を購読する

再ビルドをトリガーするために、Netlify にビルドフックを作成できます。[Settings](設定)タブに戻り、[Build & Deploy](ビルド&デプロイ)、[Build Hooks](ビルドフック)に移動します。私はこれに Hasura という名前を付けました。こちらからリンクしてください。

最後に、Hasura ダッシュボードに戻り、上の[EVENTS](イベント)タブをクリックし、フックに Netlify という名前を付けて、フックを追加します。

[Create Event Trigger](イベントトリガーの作成)ボタンをクリックすると、設定が完了します!これで、両方のアカウント間にリレーションシップが作成されました。’favoriteGames’ テーブルを更新すると、Netlify では、ビルドのトリガーとそのデータの再入力が認識されます。

この小さなアプリがきっかけで、アプリを簡単に構築できるすばらしい技術をあなたが手にすることができれば幸いです。