【10分トライ】GraphQL / Apollo Server 4

# はじめに
GraphQLを触る機会に恵まれたので、[**Apollo Server 4**](https://www.apollographql.com/)を使ってGraphQLのノリを最小限で試してみました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841759/8e75bd3f-d639-cfc5-39ee-5f6d6f73cc6f.png)

### この記事の到達点
- ローカルにGraphQLを試せる環境を **10分** で作れる
- GraphQLの凄さがチョットワカルかも？

### この記事の対象者
- GraphQLってなんぞや？
- REST API叩くのシンドイ...💦
- お手軽にGraphQLを試してみたい！

### 開発環境
- MacOS 13.4.1 (Ventura)
- npm 10.2.3

### 目次
1. [テストアプリの作成](#Chapter1)
1. [GraphQLの設定](#Chapter2)
1. [🚀 完成！](#Chapter2)

<a id="#Chapter1"></a>
# 1. テストプロジェクトの作成
最小限の構成で、Apollo Serverをローカルで試すためのプロジェクトを作ります。
```sh
# テストアプリディレクトリの作成
mkdir graphql-practice
cd graphql-practice

# npm init --yes で新しいNode.jsプロジェクトをデフォルト設定で作成
# npm pkg set type="module"　でESモジュールを使用することを宣言
npm init --yes && npm pkg set type="module"

# 今回使用する"apollo server"をインストール
npm install @apollo/server graphql

# srcディレクトリにindex.tsファイルを作成
mkdir src
touch src/index.ts

# TypeScriptプロジェクト化する
npm install --save-dev typescript @types/node
touch tsconfig.json
```

tsconfig.jsonの中身を、以下のように編集する。
※より詳細にカスタマイズしたい場合は、[TSの公式Docs](https://www.typescriptlang.org/tsconfig/)を参照。
```json:tsconfig.json
{
  "compilerOptions": {
    "rootDirs": ["src"],
    "outDir": "dist",
    "lib": ["es2020"],
    "target": "es2020",
    "module": "esnext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "types": ["node"]
  }
}
```
package.jsonの、`scripts`も以下のように編集。
また、`"type": "module"`になっていることも確認する。
```json:package.json
{
  ".....................": "その他のプロパティ"
  
  "scripts": {
    "compile": "tsc",
    "start": "npm run compile && node ./dist/index.js"
  }
  
  ".....................": "その他のプロパティ"
}
```
`npm start`して、以下のようにコンソールに出力されていればOK！
これでテストプロジェクトの枠組みは完成！
```sh
> graphql-practice@1.0.0 start
> npm run compile && node ./dist/index.js

> graphql-practice@1.0.0 compile
> tsc
```

<a id="#Chapter2"></a>
# 2. GraphQLの設定
テストプロジェクトが完成したので、いよいよGraphQLの動きを定義していく！

:::note info
vscodeで編集する場合、以下の拡張機能を入れるとGraphQLの構文をハイライトしてくれる。
[GraphQL: Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql-syntax)
:::

以下の流れを、index.tsに記述していく。
1. スキーマを定義し、どのようなデータ構造とクエリがあるかを示す
1. サンプルデータを用意する
1. クエリに対するリゾルバーを定義し、クエリに応じたデータを返す
1. ApolloServerを設定し、サーバーを起動する

```ts:index.ts
// 最新の Apollo Server 4 をインポート
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

// #graphqlで文字列をスタートさせると、対応するIDEではハイライトが入る
// 上記で紹介した拡張機能を入れるのも良き

// GraphQLのスキーマの定義
// type Book => Bookオブジェクトを定義
// type Query => クエリの定義　booksクエリは、Bookの配列を返す
const typeDefs = `#graphql

  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }
`;

// サンプルデータ（booksオブジェクト）の生成
// ※このデータがGraphQLの戻り値になる
const books = [
  {
    title: 'The Awakening',
    author: 'Kate Chopin',
  },
  {
    title: 'City of Glass',
    author: 'Paul Auster',
  },
];

// リゾルバーの定義
// 上で定義したbooksクエリの中身を定義している
// 今回は、booksオブジェクトをそのまま返す関数
const resolvers = {
  Query: {
    books: () => books,
  },
};

// GraphQLサーバーのインスタンスを生成
// 引数にtypeDefsとresolversを渡す
const server = new ApolloServer({
  typeDefs,
  resolvers,
});

// サーバーURLの定義
// 起動すると`http://localhost:4000`でアクセスできるようになる
const { url } = await startStandaloneServer(server, {
  listen: { port: 4000 },
});

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

<a id="#Chapter3"></a>
# 3. 完成！
再度`npm start`して、以下のようにコンソールに出力されていればOK！
```sh
> 🚀  Server ready at: http://localhost:4000/
```
http://localhost:4000/ にアクセスすると、以下のような画面が出る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841759/8e75bd3f-d639-cfc5-39ee-5f6d6f73cc6f.png)

Operationの部分を操作して、`▶️GetBooks`ボタンを押すと、画面右側の戻り値が変化する！
最後に、GraphQLの特徴である、必要な情報だけの取得を試してみる。
例えば、以下のように`title`だけを取得するクエリにすると...
```js
query GetBooks {
  books {
    title
  }
}
```
タイトルだけを返してくれるようになります！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1841759/5c14e3ae-883c-7fb8-abec-e5450289ca5d.png)


# おわりに・まとめ
公式チュートリアルを咀嚼しながら駆け足でやってみました！
こういう新しい()技術に触れるのはワクワクしますね！

# 参考資料

https://www.apollographql.com/docs/apollo-server/getting-started/