前回の記事では、GraphQLスキーマと、クエリやミューテーションの実行におけるその基本的な役割について学ぶことで、GraphQLサーバーの内部動作について多くのことをカバーしました。
GraphQLサーバーがGraphQLエンジンを使用してこれらの操作を実行する方法は学びましたが、実際のクライアントとサーバー間の通信、つまりクエリとその応答がネットワーク上でどのように転送されるかという側面については触れていませんでした。この記事ではそれについて説明します!
GraphQLサーバーは、お好みのプログラミング言語で実装できます。この記事ではJavaScriptに焦点を当て、サーバーの構築に役立つ利用可能なライブラリ、特に
express-graphql
、apollo-server
、graphql-yoga
について説明します。
HTTP経由でGraphQLをサービスする
GraphQLはトランスポート層に依存しない
GraphQLについて理解すべき重要な点は、データがネットワーク上で転送される方法に実際には依存しないということです。これは、GraphQLサーバーがHTTP以外のプロトコル、例えばWebSocketsや低レベルのTCPに基づいて動作する可能性があることを意味します。しかし、この記事では、現在GraphQLサーバーを実装する最も一般的な方法であるHTTPに基づいた方法に焦点を当てています。
Express.jsは強力で柔軟な基盤として使用される
以下のセクションは主にExpress.jsと、
express-graphql
やapollo-server
のようなGraphQLライブラリで使用されるミドルウェアの概念についてです。Expressに既に慣れている場合は、次のセクションに進んでください。
express、hapi、koa、sailのnpmトレンド比較
Express.jsは、JavaScriptウェブフレームワークの中で圧倒的に人気があります。そのシンプルさ、柔軟性、パフォーマンスによって輝きを放っています。
独自のウェブサーバーを始めるために必要なのは、以下のコードだけです
Node.jsでこのスクリプトを実行すると、ブラウザでhttps://:3000
にアクセスできます
サーバーのAPIにさらにエンドポイント(ルートとも呼ばれます)を簡単に追加できます
または、GETの代わりにPOSTなど、別のHTTPメソッドを使用することもできます
Expressはサーバーの実装に関して優れた柔軟性を提供し、ミドルウェアの概念を使用して機能を簡単に追加できるようにします。
Expressにおける柔軟性とモジュール性の鍵:ミドルウェア
ミドルウェアは、受信するリクエストを傍受し、リクエストが処理されている間または応答が返される前に、専用のタスクを実行することを可能にします。
本質的に、ミドルウェアは3つの引数を取る単なる関数です
req
: クライアントからの受信リクエストres
: クライアントに返される応答next
: 次のミドルウェアを呼び出す関数
ミドルウェア関数は、受信リクエストオブジェクトと送信応答オブジェクトの両方に(書き込み)アクセスできるため、特定の目的に応じてリクエストと応答を形成できる非常に強力な概念です。
ミドルウェアは、認証、キャッシュ、データ変換と検証、カスタムビジネスロジックの実行など、多くのユースケースで使用できます。以下は、リクエストが受信された時刻をログに出力する単純なロギングの例です
このミドルウェアのアプローチによって得られる柔軟性は、graphql-express
、apollo-server
、graphql-yoga
といったフレームワークで活用されており、これらはすべてExpressに基づいています!
ExpressとGraphQL
前回の記事でgraphql
関数と一般的なGraphQL実行エンジンについて学んだことを踏まえると、ExpressベースのGraphQLサーバーがどのように機能するかは既に予測できます。
ExpressがHTTPリクエストを処理するために必要なすべてを提供し、GraphQL.jsがクエリを解決する機能を提供しているため、私たちに必要なのはそれらを結びつける接着剤だけです。
この接着剤は、express-graphql
やapollo-server
のようなライブラリによって提供されており、これらはExpressのミドルウェア関数に過ぎません!
GraphQLミドルウェアがHTTPとGraphQL.jsを結びつける
express-graphql
:GraphQLミドルウェアのためのFacebook版
express-graphql
は、ExpressとGraphQL.jsで使用できるGraphQLミドルウェアのFacebook版です。ソースコードを見てみると、その中核機能がわずか数行のコードで実装されていることがわかります。
実際のところ、その主な責任は2つあります
- 受信したPOSTリクエストの本文に含まれるGraphQLクエリ(またはミューテーション)がGraphQL.jsによって実行できることを保証します。つまり、クエリを解析して
graphql
関数に転送し、実行させる必要があります。 - 実行結果を応答オブジェクトにアタッチして、クライアントに返せるようにします。
express-graphql
を使用すると、次のようにGraphQLサーバーをすばやく起動できます
このコードをNode.jsで実行すると、
https://:4000/graphql
でGraphQLサーバーが起動します
GraphQLスキーマに関する前回の記事を読んだ方なら、7行目から18行目が何のために使われているか、かなりよく理解できるでしょう。ここでは、以下のクエリを実行できるGraphQLSchema
を構築しています
しかし、このコードスニペットの新しい部分は、統合されたネットワーク層です。GraphQL.jsでクエリをインラインで記述して直接実行する(ここで示したように)のではなく、今回はサーバーを設定して、受信するクエリを待ち、それをGraphQLSchema
に対して実行できるようにしています。
サーバーサイドでGraphQLを始めるのに、これ以上多くは必要ありません。
apollo-server
:Expressエコシステム外での互換性向上
本質的に、apollo-server
はexpress-graphql
と非常によく似ており、いくつかのわずかな違いがあります。両者の主な違いは、apollo-server
がkoa
やhapi
といった他の多くのフレームワーク、およびAWS LambdaやAzure FunctionsのようなFaaSプロバイダーとの統合も可能にしている点です。各統合は、パッケージ名に適切なサフィックス(例:apollo-server-express
、apollo-server-koa
、apollo-server-lambda
)を追加することでインストールできます。
しかし、その核となる部分は、HTTPレイヤーとGraphQL.jsによって提供されるGraphQLエンジンを橋渡しする単なるミドルウェアです。上記のexpress-graphql
ベースの例と同等の実装をapollo-server-express
で行うと、次のようになります
graphql-yoga
:GraphQLサーバーを構築する最も簡単な方法
GraphQLサーバー構築時の摩擦を取り除く
express-graphql
やapollo-server
を使用する場合でも、いくつかの摩擦点があります
- 複数の依存関係のインストールが必要
- Expressの事前知識を前提としている
- GraphQLサブスクリプションの使用設定が複雑
これらの摩擦は、GraphQLサーバー構築のためのシンプルなライブラリであるgraphql-yoga
によって解消されます。これは本質的に、Express、apollo-server
、およびその他のいくつかのライブラリの上に構築された便利なレイヤーであり、GraphQLサーバーを迅速に作成する方法を提供します。(GraphQLサーバー用のcreate-react-appのようなものと考えてください。)
express-graphql
やapollo-server
で既に見たのと同じGraphQLサーバーが、graphql-yoga
ではどのように見えるかをご覧ください
GraphQLServer
は、準備済みのGraphQLSchema
インスタンスを使用するか、上記のスニペットに示されているように便利なAPI(graphql-tools
のmakeExecutableSchema
に基づく)を使用してインスタンス化できることに注意してください。
GraphQL Playground、サブスクリプション、トレーシングの組み込みサポート
graphql-yoga
には、graphql-playground
の組み込みサポートも含まれていることに注意してください。上記のコードで、https://:4000
でPlaygroundを開くことができます
graphql-yoga
は、graphql-subscriptions
およびws-subscriptions-transport
パッケージの上に構築された、GraphQLサブスクリプションのためのシンプルなAPIもすぐに利用できます。このわかりやすい例でその動作を確認できます。
graphql-yoga
で実行されるGraphQL操作のフィールドレベル分析を可能にするため、Apollo Tracingの組み込みサポートも利用できます。
結論
GraphQLSchema
とGraphQLエンジン(GraphQL.jsなど)の概念に基づくGraphQL実行プロセスについて前回の記事で議論した後、今回はネットワーク層に焦点を当てました。特に、GraphQLサーバーが実行エンジンでクエリ(またはミューテーション)を処理することでHTTPリクエストにどのように応答するかについてです。
Nodeエコシステムでは、Expressはシンプルさと柔軟性のおかげでウェブサーバーを構築するための最も人気のあるフレームワークです。その結果、GraphQLサーバーの最も一般的な実装はExpressに基づいており、特にexpress-graphql
とapollo-server
が挙げられます。両ライブラリはいくつかのわずかな違いがあるものの非常によく似ており、最も重要な違いはapollo-server
がkoa
やhapi
などの他のウェブフレームワークとも互換性がある点です。
graphql-yoga
は、他の多くのライブラリ(graphql-tools
、express
、graphql-subscriptions
、graphql-playground
など)の上に構築された便利なレイヤーであり、GraphQLサーバーを構築する最も簡単な方法です。
次回の記事では、GraphQLリゾルバに渡されるinfo
引数の内部について議論します。
次回の投稿もお見逃しなく!
Prismaニュースレターに登録する