バックエンド

GraphQLのAPIサーバーをローカルで立てるまで

shio

こんにちは、しおです。

最近GraphQLを触り始めています。
ので今回はローカル端末で GraphQLのAPIサーバーをたてるまでを簡単にまとめようと思います。

前提

今回はTypeScriptでの構築でパッケージマネージャーにbunを利用していきます。
bunの部分は適宜npmやyarnで読み替えても問題ないかと思います。

また、GraphQLのサーバーにはApollo Serverを利用します。
Apollo Serverはオープンソースの GraphQLサーバーです。
公式ドキュメント

単体で GraphQLサーバーを立ち上げることができ、Expressなどのミドルウェアとしても実行できるようです。
今回は単体でサーバーを立てる方で実践します。

実践

ではここから実際にサーバー起動までをやってみます。

準備

まずはプロダクトの準備からです

mkdir graphql-sample
cd graphql-sample
bun init

initの際のエントリーポイントなどは全てデフォルトで作成します。

Apollo Serverをパッケージに追加

必要なパッケージを追加します。

bun add  @apollo/server graphql

index.tsの編集

initで追加されたindex.tsを編集していきます。
編集内容は公式のドキュメントの内容を元にします。
詳細はドキュメントも合わせて確認するとわかりやすいかと思います。
公式ドキュメント

まずはスキーマの定義です。
スキーマはクライアントが利用するデータ構造の定義になります。

const typeDefs = `#graphql
  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }
`;

次にデータの準備です。
今回はデータをハードコードしますが、データベースや別のREST APIなどからデータを取得することができます。

const books = [
  {
    title: 'The Awakening',
    author: 'Kate Chopin',
  },
  {
    title: 'City of Glass',
    author: 'Paul Auster',
  },
];

データセットが準備できたら、次はリゾルバの定義です。
リゾルバは、スキーマに対してどのデータを返すのかを決める関数になります。
上記で定義したデータbooksをそのまま返すようにすれば大丈夫です。

const resolvers = {
  Query: {
    books: () => books,
  },
};

スキーマとリゾルバの定義ができたらApollo Serverを立てることができます。
ApolloServerインスタンスにスキーマ定義とリゾルバ定義を渡して、startStandaloneServerを呼び出せばサーバーが起動します。
パッケージからのインポートが必要になるので、忘れずにしておきましょう。

import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";

// 中略

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

const { url } = await startStandaloneServer(server, {
  listen: { port: 4000 },
});

console.log(`🚀  Server ready at: ${url}`);

ここまでで最終的なindex.tsは下記のようになります。

import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";

const typeDefs = `#graphql
  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }
`;

const books = [
  {
    title: "The Awakening",
    author: "Kate Chopin",
  },
  {
    title: "City of Glass",
    author: "Paul Auster",
  },
];

const resolvers = {
  Query: {
    books: () => books,
  },
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

const { url } = await startStandaloneServer(server, {
  listen: { port: 4000 },
});

console.log(`🚀  Server ready at: ${url}`);

index.tsの実行

さっそく実行してみましょう。

bun run index.ts

ポート番号を変えていなければ
http://localhost:4000 にブラウザからアクセスできるはずです。
アクセスするとApollo Sandboxというローカル開発で利用できる開発ツールが開きます。

booksというクエリを定義したので、そのクエリを実行してみましょう。
下記のようなクエリの入力欄に入れて実行します。

query GetBooks {
  books {
    title
    author
  }

レスポンスにはデータに定義したものが返ってくることが確認できます。

もちろんcurlを利用してデータを取得することも可能です。
あえてauthorのフィールドだけ取得してみます。

curl http://localhost:4000 -H "Content-Type: application/json" -d '{"query": "{books { author }}"}'

>> {"data":{"books":[{"author":"Kate Chopin"},{"author":"Paul Auster"}]}}

無事に取得できましたね。
ここまででサーバ起動も完了です。

終わりに

いかがでしたでしょうか、自分はApollo Serverに初めて触れたのですが、構築が思いのほか簡単で驚いています。
データセットについては実際はDBなどから取得することになると思うので、そこは別途実践していきたい部分です。
またGraphQLの利点などもまとめられたら別の記事にしてみようかと思います。

AUTHOR
shio
shio
記事URLをコピーしました