Blog

GraphQLを使ってAPIサーバーを実装してみた

この記事は、リレーブログ企画「24新卒リレーブログ」の記事です。

はじめに

こんにちは。初めまして、新卒1年目の塚崎です。
現在、ジョブローテの1期目として、第一開発チーム(https://engineering.nifty.co.jp/blog/26940)でとあるサイトをリニューアルするプロジェクトを進めています。このリニューアルではフロントエンドでNext.jsを採用し、バックエンドではGraphQLを採用しています。今回のリニューアルで私は主にフロントエンドの実装を担当しているのですが、GraphQLについても学んだので、今回はGraphQLを使ったAPIサーバーの実装について記事にしたいと思います。

GraphQLとは?

GraphQL(https://graphql.org/)とは、Meta社によって開発されたWeb APIのクエリ言語です。GraphQLでは、クライアントが必要なデータだけを指定し、サーバーから取得することができるため、REST APIの課題であったデータの過剰取得を防ぎ、効率良くデータの取得が行えます。また、REST APIでは複数のエンドポイントからデータの取得を行うのに対して、GraphQLでは単一のエンドポイントから一度のリクエストで全てのデータを取得することができます。他にもスキーマと呼ばれる型やクエリを定義する仕組みによって、安全に開発ができることも大きなメリットです。

特徴

  • 柔軟なデータ取得
    • クライアント側で必要なデータだけを指定して取得可能
  • 単一のエンドポイント
    • 単一のエンドポイントで全てのデータ操作が可能
  • 強力な型システム
    • スキーマを定義することで型の安全性が保証される
  • 階層的な構造
    • データの関係性をクエリの構造に反映できる
  • リアルタイム機能
    • サブスクリプション機能を利用し、リアルタイムにデータを取得できる
  • バージョン管理が不要
    • 新しいフィールドの追加を容易に行うことができ、バージョン管理が不要

GraphQLサーバーの実装

実際にGraphQLサーバーを実装し、データの取得までをやってみます。
まずは任意の場所でGraphQL用のディレクトリ(graphql-server-example)を作成します。

npmで初期化します。

依存ライブラリである@apollo/serverとgraphqlをインストールします。

package.jsonを開き、scripts"start": "node index.js"を追加します。

スキーマの作成

今回は例としてアーティスト情報を返すAPIサーバーを構築してみます。
まずindex.jsを作成し、以下のようにスキーマ(APIの型やクエリを定義するもの)を書きます。
typeDefsはスキーマを定義する変数です。VSCodeでは以下の拡張機能を追加し、テンプレートリテラルの開始に#graphqlと書くことでシンタックスハイライトが機能するようになります。
今回はID、アーティスト名、ジャンルの3つをアーティストオブジェクトとして定義しました。またクエリとして全てのアーティストオブジェクトを取得するクエリも定義しています。

拡張機能(GraphQL: Syntax Highlighting)
https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql-syntax

データの作成

次にサーバーから返すデータを作成します。
通常、クライアントに返すデータはデータベースと接続し、そこから取得を行いますが、今回はデータを配列でハードコーディングすることで擬似的に用意します。

リゾルバの作成

ここまででスキーマを定義し、データも用意することができました。あとはサーバーからフロントへデータを返す処理を追加すれば良さそうです。
データを返すリゾルバを定義します。リゾルバとは、データベースなどからデータを取得し、スキーマで定義された型に合わせてデータを返す処理を担当します。
今回、スキーマで定義したallArtistsは全てのアーティストオブジェクトを返すクエリのため、用意した配列のデータをそのまま返す処理を追加しています。
実際にはデータベースからデータを取得した際に、それがそのまま返せるケースは少ないので、リゾルバでスキーマと合うように整形してあげる必要があります。

サーバーの起動

最後にApollo Serverを初期化する処理を追加してあげましょう。

サーバーを起動します。

npm start

サーバーを起動するとターミナルに以下が出力されていると思うので、リンクをブラウザで開きます。

Server ready at: http://localhost:4000/

リンクを開くと以下のような画面に遷移します。

この画面ではクエリを実行したり、クエリのレスポンス結果を確認したりすることができます。

それでは実際にクエリを実行してみましょう。

実行結果です。クエリで指定したフィールドの値を取得することができました。

フィールドの追加

次にアーティスト数を取得するフィールドを追加してみましょう。

フィールド(totalArtists)を追加したので、それに対応するリゾルバを作成する必要があります。今回は、アーティスト数を返すリゾルバとしたので、単純にアーティストの配列の長さを返します。

サーバーを再起動し、変更を反映させます。

リンクを開き画面の左側を見ると、フィールドとしてtotalArtistsが追加されていることが分かります。

クエリを実行してみましょう。

実行結果です。全てのアーティスト情報とアーティスト数を取得することができました。このようにクエリには複数のフィールドを追加して、実行することもできます。こういったケースでは、REST APIでは2つのエンドポイントに対してリクエストを送信する必要がありますが、GraphQLでは1回のリクエストで複数のデータを取得することができます。

最後に各アーティストがリリースしたアルバム情報を取得できるように実装を追加してみます。

アルバムオブジェクトをスキーマとして定義します。またアーティストオブジェクトにリリースしたアルバム情報をリストで返すフィールド(releasedAlbums)も追加してあげましょう。

アルバム情報のデータを用意します。

リゾルバを追加します。配列のfilterメソッドを使用することで、アーティストがリリースしたアルバム情報をリストで取得しています。

サーバーを再起動し、変更を反映させます。
クエリを実行してみます。

以下のようにデータを取得することができたと思います。

まとめ

今回は、とあるプロジェクトのリニューアルでGraphQLについて学び、APIサーバーの実装をやってみました。実際にプロジェクトに導入し、実装を進める中で必要なデータだけを簡単に取得できる点や事前にスキーマを固めることでバックエンドの開発を待たずにフロントエンドの実装が進められる点がメリットとして実感できました。しかし、今回学んだ内容はGraphQLの基礎的な内容になるため、キャッシュやスキーマファーストといったパフォーマンスや設計に関する部分もこれから学んでいく必要があると感じました。ニフティでは、書籍購入費用補助制度やUdemyなども使えるので、それらを活用してこれからも勉強していきたいです。

次回は、けにさんです。どんな記事になるか楽しみですね!

参考資料

ニフティでは、
さまざまなプロダクトへ挑戦する
エンジニアを絶賛募集中です!
ご興味のある方は以下の採用サイトより
お気軽にご連絡ください!

Tech TalkやMeetUpも開催しております!
こちらもお気軽にご応募ください!

connpassでニフティグループに
参加いただくと
イベントの
お知らせが届きます!