GraphQL APIをVueJSフロントエンドに接続する方法

この記事はMarion Schleiferのこの記事を翻訳したものです
[**How to connect your GraphQL API to your VueJS Frontend**
*I recently wrote a blogpost about how to create an API with Hasura’s GraphQL engine. If you are not familiar with…*medium.com](https://medium.com/@marion.schleifer/how-to-connect-your-graphql-api-to-your-vuejs-frontend-61d8e8e455db)

私は最近、HasuraのGraphQLエンジンを使ってAPIを作成する方法についての[ブログ記事](https://medium.com/@takeshiamano/graphql-api%E3%81%AE%E5%88%9D%E5%BF%83%E8%80%85%E5%90%91%E3%81%91%E3%82%AC%E3%82%A4%E3%83%89-8038404d198)を書きました。 GraphQLにまだ慣れていない方は、まずこの記事を読むことをお勧めします。それでは、非常にシンプルなVueアプリを作成し、それをGraphQL APIに接続する方法を学びましょう。

Vueアプリの作成中に何か不明な点がある場合、または完全な解決策を見たい場合は、いつでもこのプロジェクトを[Github](https://github.com/marionschleifer/harry-potter-app)で見ることができます。

目次 
Vueプロジェクトを作成する
映画リストコンポーネント
映画詳細コンポーネント
ムービーコンポーネントを追加する
GraphQL APIへの接続
GraphQL APIから実際のデータを取得する
映画リスト
映画を追加
この後は？
コミュニティに参加する

## Vueプロジェクトを作成する

    vue create harry-potter-app

デフォルトのプリセットを選択して、お気に入りのエディタでプロジェクトを開きます。アプリの外観を少しきれいにするために、Milligramライブラリを追加します。 index.html内に<head>の内側に次の3行を追加します。

    <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">

    <link rel="stylesheet" href="//cdn.rawgit.com/necolas/normalize.css/master/normalize.css">

    <link rel="stylesheet" href="//cdn.rawgit.com/milligram/milligram/master/dist/milligram.min.css">

端末に移動し、プロジェクトにcdして、次のようにローカルに入力してアプリケーションを実行します。

yarnの場合は：

    yarn serve

Npmの場合は

    npm run serve

Vueのロゴが表示されたVueのHello Worldページが表示されます。

<iframe src="https://cdn-images-1.medium.com/max/2000/1*F22ZNIWud7_amT3zo-JaNw.png" frameborder=0></iframe>

[前回の記事](https://medium.com/@takeshiamano/graphql-api%E3%81%AE%E5%88%9D%E5%BF%83%E8%80%85%E5%90%91%E3%81%91%E3%82%AC%E3%82%A4%E3%83%89-8038404d198)で作成したHarry Potter APIを見ると、movies、characters、actors、scenesといういくつかのテーブルがあることがわかります。私たちのVueアプリでしたいことは、映画用のコンポーネントを作成することです。最後に、1つのmovieを表す複数のコンポーネントで構成されるmovieのリスト用のコンポーネントが必要です。そしてmovieを追加することを可能にするコンポーネントを作成します。

## Movieリストコンポーネント

始めましょう。まず、MovieListコンポーネントをApp.vueファイルに登録します。ファイル内で、<HelloWorld />コンポーネントを<movies-list />に置き換える必要があります。いまはまだ失敗します。新しいコンポーネントを登録していないからです。コンポーネントリストの同じファイルのもう少し下の部分で、名前を変更したコンポーネントを正しい場所からインポートし、HelloWorldコンポーネントをMoviesListコンポーネントに置き換えます。完了したら、次のようになります。

<iframe src="https://medium.com/media/3c22b29106193f88105cd84ffbaabd7b" frameborder=0></iframe>

それでは、HelloWorld.vueファイルの名前をMoviesList.vueに変更する必要があります。ファイル内で、`<template>`と`<script>`を置き換えて、次のようになります。

<iframe src="https://medium.com/media/964db52bdee0c7104f41b21674844ff0" frameborder=0></iframe>

ここで何が起こっているかを説明します。テンプレートの内側に、v-forを使ってすべてのmovieを反復処理する`<div>`を追加します。各movieの識別方法をVueに指示する必要があります。各movieの識別方法は、そのmovieのIDで行います。二重の中括弧を使用して、ブラウザに何を表示するかをVueに指示します。これは、この場合はmovieのIDです。 `<script>`タグ内に、表示するデータを定義します。今のところ、定義したIDを持つmovieであるダミーデータを表示します。ブラウザでこのアプリを見ると、VueのロゴとmovieのIDが表示されます。

![](https://cdn-images-1.medium.com/max/2200/1*7ABjgPjGd0p-VvvTHhHYGg.png)

## Movie詳細コンポーネント

前述したように、1つのmovieを表示するためのコンポーネントも必要です。これの目的は、ダミーデータを使用する代わりに、実際のMovieItemのコレクションをMoviesListに後で表示できるようにすることです。それでは、componentsフォルダの中を進んで、MovieItem.vueという新しいファイルを作成しましょう。 MoviesListの各MovieItemについて、title、director、composer、およrelease dateを表示します。それでは、先に進み、コンポーネントをMovieItem.vueファイルに追加しましょう。

<iframe src="https://medium.com/media/6428e158f1f01ff2d9dc3e16e7304dd0" frameborder=0></iframe>

そのためには、単純な<div>の代わりに<movie-item>コンポーネントを使用するように3行目を変更する必要があります。また、8行目で、対応するファイルからMovieItemをインポートする必要があります。最後に、11行目で、MovieItemが現在のファイル内でmovieのリストのインスタンスとして使用されるコンポーネントであることを説明する必要があります。

ブラウザをリロードすると、次のようになります。

![](https://cdn-images-1.medium.com/max/2000/1*5TB93HZ_gTHVjQGHRpBLDA.png)

## movieコンポーネントの追加

それでは、新しいmovieをアプリケーションに追加する機能を追加しましょう。そのためには、componentsフォルダの中に、AddMovie.vueという新しいファイルを作成し、今のところ空のままにします。今度はApp.vueを開き、`<template>`内で、`<movies-list>`コンポーネントの前に`<add-movie />`コンポーネントを追加します。また、MoviesListコンポーネントと同様に、正しい場所からコンポーネントをインポートし、AddMoviesコンポーネントをコンポーネントリストに追加する必要があります。完了したら、`<template>`と`<script>`は次のようになります。

<iframe src="https://medium.com/media/9f70c317508f8d9884539e4478655559" frameborder=0></iframe>

AddMovie.vueファイル内に、新しいムービーを作成するためのフォームを追加します。 APIを見ると、movieテーブルにどのようなフィールドがあるのか​​がわかります。今のところ、私たちはタイトル、監督、作曲家そしてリリース日を持っている映画を作成することができたいです。ファイルは次のようになります。

<iframe src="https://medium.com/media/637aa361574f8b10cc1c91a033a64e24" frameborder=0></iframe>

これはmovieのフィールドを入力して送信することを可能にする非常に単純なフォームです。まだコンポーネントにメソッドを追加していないので、送信ボタンをクリックしても何も起こりません。

ブラウザをリロードすると、次のようになります。

![](https://cdn-images-1.medium.com/max/2000/1*FIW7Dw7Soo9pb3SLVPNC7g.png)

## GraphQL APIへの接続

次のステップは、前回の投稿で作成したGraphQL APIにVueアプリを接続して、ダミーデータの代わりに実際のデータを表示できるようにすることです。それでは始めましょう。

前回の記事では、GraphiQLツールでクエリを実行する方法を説明しました。 Hasuraコンソールに移動してGraphiQLで、すべてのムービーのリストを取得するためのメソッドと、新しいムービーを追加するための機能をテストしましょう。

<iframe src="https://medium.com/media/64e610be98417a8a131a02d6ea6a88d1" frameborder=0></iframe>

さて、Vueプロジェクトから、私たちはまさにこれらのメソッドを呼び出したいです。そのためには、Apolloクライアントを使います。 Apolloは、簡単な言語であなたのAPIに問い合わせをすることを可能にするGraphQLプラットフォームです。プロジェクトフォルダのコマンドラインで次のコマンドを実行して、Apolloをインストールしましょう。

npmの場合：

    npm install apollo-client apollo-cache-inmemory apollo-link-http graphql-tag graphql --save

yarnの場合：

    yarn add vue-apollo graphql apollo-client apollo-link apollo-link-http apollo-cache-inmemory graphql-tag

まず、Hasuraプロジェクトへのリンクを確立し、Apolloをインスタンス化する必要があります。 main.jsを次のように変更します。

<iframe src="https://medium.com/media/f11a677f9ca1aa2e09076e340bf29744" frameborder=0></iframe>

これを見てみましょう。最初に、インストールしたばかりのライブラリをインポートする必要があります。それらをこのファイルで使用するからです。 HttpLinkを使用して、12〜14行目でGraphQL APIへの接続を確立します。 HasuraプロジェクトのGraphiQLツールに独自のカスタムリンクがあります。

![](https://cdn-images-1.medium.com/max/2000/1*KwNXuYSIfvQpwsCHHCftBA.png)

次に、16行目から20行目で、ApolloClientのインスタンスを作成します。引数として、HttpLinkを渡して、データが正しいAPIからポーリングされるようにします。次にキャッシュを渡します。 InMemoryCacheはApolloClientのデフォルトのキャッシュ実装であるため、これを使用します。最後に開発ツールに接続するためのオプションを渡します。そのため、デバッグが必要な場合に備えて、クロムインスペクタにApolloタブが表示されます。

22行目では、VueインスタンスをVueApolloを使用するように設定しています。

Vueアプリからクエリやmutationを作成できるようにするには、ApolloProviderのインスタンスを作成する必要があります（24〜26行目）。 Apolloクライアントに渡して、これらの操作をコミットします。

最後に、28行目から32行目で、Apolloプロバイダーが渡されるVueアプリを起動し、アプリ全体でデータベースのクエリと操作を行えるようにします。

## GraphQL APIからデータを取得する

これまでのところ、Vueフロントエンドにダミーデータを表示しています。さて、実際のデータを表示したいです。 MoviesListには、現在データベースに保存されているmovieを表示します。また、映画をデータベースに保存してフロントエンドに表示できるように、movieを追加できるようにしたいと考えています。

### Moviesリスト

データベースから映画を表示するには、MoviesList.vueを次のように変更しましょう。

<iframe src="https://medium.com/media/27abed89f18d66dc899c242de5d86d46" frameborder=0></iframe>

`<script>`タグの中に、GraphQLをインポートする必要があります。これにより、クエリを実行できるようになります。 11〜21行目では、映画のリストを取得するためのGraphQLクエリを定義しています。

デフォルトのexport default関数内で、ダミーデータを削除し、データベースからポーリングした映画のリストを返します。また、ApolloにどのクエリをAPIに送るべきかを伝える必要があります。そして先に定義したGET_MOVIESクエリを渡します。

ブラウザを更新すると、データベースから映画の全リストを見ることができます。

![](https://cdn-images-1.medium.com/max/2000/1*8gEy4JXg3WrmFNyw8TwyjA.png)

やったできました！

### movieの追加

これまでのところ、フォームを送信しても何も起こりません。私たちは今、私たちのフォームの上に映画を追加できるようにしたいです。これには、AddMovie.vueファイルにいくつかの変更を加える必要があります。

<iframe src="https://medium.com/media/ab575b082f3d34c2bd1335eafbb10b77" frameborder=0></iframe>

繰り返しになりますが、`<script>`タグの中に、GraphQLをインポートする必要があります。また、InMemoryCacheをインポートする必要があります。その理由はほんの少しのうちにわかります。

17〜39行目で、データベースに映画を追加するためのmutationを定義します。まず、渡されるパラメータを定義します。次に、movieを挿入するためのオブジェクトとして渡します。そして第三にmutationの戻り値が先程作成したmovieのidであることを記述します。

export default関数内の最も重要な変更は52〜67行目に反映されており、送信ボタンがクリックされたときの動作を定義しています。まず、ボタンをクリックしたときに送信されるフォームのデフォルトの動作を防ぐ必要があります。次にmutationに渡すデータを定義します。次に、$ apolloインスタンスへのmutationを呼び出し、オブジェクト作成のために変数を渡します。最後に、movieリストを更新する必要があります。新しく追加されたmovieがリストに表示されるようにブラウザをリロードしたくないためです。これにはキャッシュが必要です。以前にmovieをリストするためにクエリを実行したので、キャッシュからそれを再フェッチすることができます。

## この後は?

よくできました！これで小さなVueアプリを作成しそれをGraphQL APIに接続しました。これはとても簡単でしたね。しかし、これはほんの始まりです！我々のアプリに追加できるもっとたくさんの機能があります。たとえば、映画の更新や削除などです。または各映画のキャラクターとそれに対応する俳優を表示します。[ Hasuraのドキュメント](https://docs.hasura.io/1.0/graphql/manual/index.html)を調べてください。このアプリを拡張するために必要なものすべてを見つけることができます。

## コミュニティに参加しましょう

Hasuraはますます多くの開発者によって使用されています。フレンドリーなコミュニティに参加して、最新情報を入手してください。

Hasuraであなた自身のプロジェクトを構築したい場合は、[ここから](https://discordapp.com/invite/hasura)discordのチャンネルに参加することができます。すでにかなり大きなコミュニティがあり、あなたはすぐに助けを得るでしょう。

🐦[Twitter](https://twitter.com/hasurahq)

️⭐[️Github](https://github.com/hasura/graphql-engine)

[Mediumの元の記事](https://medium.com/@takeshiamano/graphql-api%E3%82%92vuejs%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%83%89%E3%81%AB%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95-545e06421a7e)