はじめに
こんにちは。開発歴4ヶ月のエンジニアです。主にバックエンドをメインに開発しています。
今回はGraphQLについて学習したことを書いていきます。
GraphQLって?
GraphQLは、APIのクエリ言語であり、既存のデータでこれらのクエリを実行するためのランタイムです。
GraphQL公式サイトから
クエリ言語?ランタイム?よくわからないので調べます。
クエリ言語
クエリ言語はGraphQLサーバーに対してリクエストするための言語です。
データを取得するためのquery、データを更新するためのmutation、サーバーサイドからのイベント通知であるsubcriptionの3種類があります。
クエリの種類 | 意味 | 効果 |
---|---|---|
query | データの取得 | GET |
mutation | データの更新 | POST/PUT/DELETE |
subcription | イベントの通知 | Websocket |
※GraphQLサーバー:クエリ言語を使うために必要なサーバー。データソースと通信して必要に応じてデータを取得、変更する役割を担う。
※サーバーサイド:サーバの中で動くプログラム
※ランタイム:プログラムとかを動かすとき(実行時)のこと。
結局のところGraphQLは、クエリ言語を使うために必要な部品といったところでしょうか。
GraphQLの特徴
GraphQLの特徴はエンドポイントが1つだけな点です。
エンドポイントとはAPIにアクセスするために必要なURIのことです。
REST APIでは各リソースごとにリクエストをしないといけず、リクエストの回数とリソースの数が比例します。
例えば、「ユーザー情報」、「フォロワー一覧」、「投稿一覧」を取得するには合計3回のリクエストが必要になります。
一方GraphQLは後述したように、必要な情報全てを1つのエンドポイントから一回のリクエストで取得することが出来ます。
つまり1回のリクエストにしてHTTPリクエストの回数を減らすことができるし、クエリを実行する時に条件を細かく設定できるので必要なデータだけ取得することが出来ます。
実際にGraphQLを動かしてみる
調べているだけでは中々イメージが掴みづらいので実際に動かしてみます。
Apolloを使ってGraphQL Serverを構築
Apolloは簡単にGraphQLServerを構築できるライブラリです。ApolloServerの[Get started]
(https://www.apollographql.com/docs/apollo-server/getting-started/)を参考にSetupしていきます。
- 新しいプロジェクト用フォルダ作成
mkdir graphql-server-example
cd graphql-server-example
- 新しいNode.jsプロジェクトをnpmで初期化
npm init --yes
- 実行結果
Wrote to /Users/i.kohei.noguchi/graphql-server-example/package.json:
{
"name": "graphql-server-example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
必要なライブラリをインストール
Apollo Serverを実行するアプリケーションには、apollo-server
とgraphql
の2つをインストールする必要があります。
npm install apollo-server graphql
- 実行結果
added 113 packages, and audited 114 packages in 10s
3 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
実行するとnode_modules
ディレクトリに内容が保存されます。
続いてプロジェクトのルートディレクトリにindex.js
を作成して以下を記述します。
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type User {
name: String
age: String
gender: String
}
type Query {
users: [User]
}
`;
const users = [
{
name: 'noguko',
age: '28',
gender: 'female'
},
{
name: 'noguo',
age: '30',
gender: 'male'
},
];
const resolvers = {
Query: {
users: () => users,
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
サーバーを起動
以下のコマンドでserverを起動します。
node index.js
すると以下が表示されるのでhttp://localhost:4000/
にアクセスします。
🚀 Server ready at http://localhost:4000/
クエリを実行する
ApolloSandboxを使ってクエリを実行していきます。
Query your server
をクリックすると以下のページが表示されます。
ページの左側がスキーマを検索できたり実行できるクエリの一覧を確認することができます。
中央がクエリを書くエディター部分で実行結果はその横の右側に表示されます。
続いて先程index.js
に書いた部分のテストをします。
正常に動作するかクエリを書いて、レスポンスがあるか確認します。
GraphQLのクエリはルート型で決まります。
ルート型はQueryやMutation、Subscriptionなどデータソースに対する操作を表現する型です。
青色部分のExampleQuery
をクリックしてクエリを実行すると右側にレスポンスが返ってきます。
今回の例ではUserというスキーマを定義してその下にデータソースを定義しています。
スキーマとはGraphQL APIの仕様を表現するもので、クライアントがクエリできるデータの構造を定義するためのものです。
// スキーマの定義
const typeDefs = gql`
type User {
name: String
age: String
gender: String
}
type Query {
users: [User]
}
`;
// データソース
const users = [
{
name: 'noguko',
age: '28',
gender: 'female'
},
{
name: 'noguo',
age: '30',
gender: 'male'
},
];
上記ではスキーマとデータソースを定義しているだけで実際のデータ操作をするにはリゾルバーを作成する必要があります。↓
// リゾルバ関数を定義してクエリ実行時のデータ操作を行う
const resolvers = {
Query: {
users: () => users,
},
};
最後にクライアント側からクエリを実行することによってデータソースへのアクセスが可能になります。
GraphQLは必要なデータだけ取得することが可能です。
もしname
の情報のみ欲しい場合はage
とgender
をクエリ部分から削除すればname
のデータのみ表示されます。
おわりに
実際にGraphQLを動かしてみて今まで理解が曖昧だったクエリ言語やスキーマ言語、リゾルバーの意味と基本的な文法を理解できて少し前進できました。
また必要なデータだけをリクエストできるのは凄い便利だと感じました。GraphQLの技術を使いこなせるように今後もインプットとアウトプットを繰り返して行こうと思います。