2017年11月28日

GraphQLサーバーの基礎:ネットワーク層

GraphQLサーバーの構造と実装(パートII)。

GraphQL Server Basics

前回の記事では、GraphQLスキーマと、クエリとmutationを実行する際のその基本的な役割について学ぶことで、GraphQLサーバーの内部構造について多くのことを説明しました。

GraphQLサーバーがGraphQLエンジンを使用してこれらの操作を実行する方法を学びましたが、実際のクライアントサーバー間の通信の側面、つまり、クエリとそのレスポンスがネットワーク上でどのように転送されるかという問題には触れていません。この記事ではそれについて説明します!

GraphQLサーバーは、お好みのプログラミング言語で実装できます。この記事ではJavaScriptに焦点を当てています。また、サーバーの構築に役立つ利用可能なライブラリ、特にexpress-graphqlapollo-servergraphql-yogaについて説明します。

HTTP経由でのGraphQLの提供

GraphQLはトランスポート層に依存しません

GraphQLについて理解するべき重要なことは、実際にはデータがネットワーク上でどのように転送されるかに依存しないということです。これは、GraphQLサーバーがHTTP以外のプロトコル(WebSocketやより低レベルのTCPなど)に基づいて動作する可能性があることを意味します。ただし、この記事では、今日GraphQLサーバーを実装する最も一般的な方法(実際にHTTPに基づいている)に焦点を当てています。

Express.jsは強力で柔軟な基盤として使用されています

次のセクションでは、主にExpress.jsとそのミドルウェアの概念について説明します。これは、express-graphqlapollo-serverのようなGraphQLライブラリで使用されています。すでにExpressに慣れている場合は、次のセクションに進んでください。

Comparison of express, hapi, koa and sail on npm trendsnpmトレンドにおけるexpresshapikoasailの比較

Express.jsは、最も人気のあるJavaScriptウェブフレームワークです。そのシンプルさ、柔軟性、パフォーマンスのおかげで優れています。

独自のウェブサーバーを始めるために必要なのは、次のようなコードです。

このスクリプトをNode.jsで実行した後、ブラウザでhttp://localhost:3000にアクセスできます。

サーバーのAPIにエンドポイント(ルートとも呼ばれます)を簡単に追加できます。

または、別のHTTPメソッド(たとえば、GETの代わりにPOST)を使用します。

Expressは、サーバーの実装に関して優れた柔軟性を提供し、ミドルウェアの概念を使用して機能を簡単に追加できるようにします。

Expressにおける柔軟性とモジュール性の鍵:ミドルウェア

ミドルウェアを使用すると、受信リクエストをインターセプトし、リクエストが処理されている間またはレスポンスが返される前に、特定のタスクを実行できます。

本質的に、ミドルウェアは3つの引数を取る関数にすぎません。

  • req:クライアントからの受信リクエスト
  • res:クライアントに返されるレスポンス
  • next:次のミドルウェアを呼び出す関数

ミドルウェア関数は、受信リクエストオブジェクトと送信レスポンスオブジェクトの両方に(書き込み)アクセスできるため、特定の目的に応じてリクエストとレスポンスを形成できる非常に強力な概念です。

ミドルウェアは、認証キャッシングデータ変換検証カスタムビジネスロジックの実行など、多くのユースケースに使用できます。リクエストを受信した時刻を出力するロギングの簡単な例を次に示します。

このミドルウェアアプローチを通じて得られる柔軟性は、graphql-expressapollo-servergraphql-yogaなどのフレームワークによって活用されており、これらはすべてExpressに基づいています!

ExpressとGraphQL

前回の記事で学んだgraphql関数とGraphQL実行エンジンに関するすべてを踏まえると、ExpressベースのGraphQLサーバーがどのように機能するかをすでに予想できます。

ExpressはHTTPリクエストを処理するために必要なすべてを提供し、GraphQL.jsはクエリを解決する機能を提供するため、私たちに必要なのはそれらの間の接着剤だけです。

この接着剤は、express-graphqlapollo-serverのようなライブラリによって提供されており、これらはExpressのミドルウェア関数にすぎません!

GraphQLミドルウェアはHTTPとGraphQL.jsを結合します

express-graphql:Facebook版GraphQLミドルウェア

express-graphqlは、ExpressとGraphQL.jsで使用できるFacebook版GraphQLミドルウェアです。そのソースコードを見ると、そのコア機能はわずか数行のコードで実装されていることに気付くでしょう。

実際、その主な責任は2つあります。

  • 受信POSTリクエストの本文に含まれるGraphQLクエリ(またはmutation)がGraphQL.jsによって実行されるようにします。したがって、クエリを解析し、実行のためにgraphql関数に転送する必要があります。
  • 実行結果をレスポンスオブジェクトにアタッチして、クライアントに返せるようにします。

express-graphqlを使用すると、GraphQLサーバーを次のようにすばやく起動できます。

このコードをNode.jsで実行すると、http://localhost:4000/graphqlでGraphQLサーバーが開始されます。

GraphQLスキーマに関する前回の記事を読んだことがあるなら、7〜18行目が何に使用されているかをかなりよく理解できるでしょう。次のクエリを実行できるGraphQLSchemaを構築します。

ただし、このコードスニペットの新しい部分は、統合されたネットワーク層です。クエリをインラインで記述してGraphQL.jsで直接実行するのではなく(こちらで実証されているように)、今回は、GraphQLSchemaに対して実行できる受信クエリを待機するようにサーバーを設定しているだけです。

サーバー側でGraphQLを始めるには、これ以上多くのものは必要ありません。

apollo-server:Expressエコシステム外でのより良い互換性

本質的に、apollo-serverexpress-graphqlと非常によく似ており、いくつかの小さな違いがあります。2つの主な違いは、apollo-serverkoaやhapiなどの他の多くのフレームワークや、AWS LambdaやAzure FunctionsのようなFaaSプロバイダーとの統合も可能にしていることです。各統合は、パッケージ名の対応するサフィックス(apollo-server-expressapollo-server-koaapollo-server-lambdaなど)を追加することでインストールできます。

ただし、コアでは、HTTPレイヤーとGraphQL.jsによって提供されるGraphQLエンジンをブリッジするミドルウェアでもあります。上記のexpress-graphqlベースの例と同等の実装がapollo-server-expressでどのように見えるかを次に示します。

graphql-yoga:GraphQLサーバーを構築する最も簡単な方法

GraphQLサーバーを構築する際の摩擦を取り除く

express-graphqlまたはapollo-serverを使用している場合でも、さまざまな摩擦点があります。

  • 複数の依存関係のインストールが必要
  • Expressの事前知識を前提とする
  • GraphQL subscriptionsを使用するための複雑な設定

この摩擦は、GraphQLサーバーを構築するためのシンプルなライブラリであるgraphql-yogaによって取り除かれます。基本的には、Express、apollo-server、およびGraphQLサーバーをすばやく作成する方法を提供するための他のいくつかのライブラリの上に構築された便利なレイヤーです。(GraphQLサーバー用のcreate-react-appのようなものと考えてください。)

express-graphqlapollo-serverですでに見たのと同じGraphQLサーバーがどのように見えるかを次に示します。

GraphQLServerは、GraphQLSchemaの準備ができたインスタンスを使用するか、上記のコードスニペットに示すように、便利なAPI(graphql-toolsmakeExecutableSchemaに基づく)を使用してインスタンス化できることに注意してください。

GraphQL Playground、Subscriptions、Tracingの組み込みサポート

graphql-yogaにはgraphql-playgroundの組み込みサポートもあることに注意してください。上記のコードを使用すると、http://localhost:4000でPlaygroundを開くことができます。

graphql-yogaには、graphql-subscriptionsおよびws-subscriptions-transportパッケージの上に構築された、GraphQL subscriptions用のシンプルなAPIもすぐに利用できます。この簡単な例でその仕組みを確認できます。

graphql-yogaで実行されるGraphQL操作のフィールドレベル分析を有効にするために、Apollo Tracingの組み込みサポートもあります。

結論

GraphQLSchemaとGraphQLエンジン(GraphQL.jsなど)の概念に基づいてGraphQL実行プロセスについて議論した後、前回の記事では、今回はネットワーク層に焦点を当てました。特に、GraphQLサーバーが実行エンジンでクエリ(またはmutation)を処理することにより、HTTPリクエストにどのように応答するかについて説明しました。

Nodeエコシステムでは、Expressはそのシンプルさと柔軟性のおかげで、ウェブサーバーを構築するための最も人気のあるフレームワークです。その結果、GraphQLサーバーの最も一般的な実装はExpressに基づいており、特にexpress-graphqlapollo-serverが挙げられます。どちらのライブラリもいくつかの小さな違いはありますが非常によく似ており、最も重要な違いは、apollo-serverkoahapiのような他のウェブフレームワークとも互換性があることです。

graphql-yogaは、他の多くのライブラリ(graphql-toolsexpressgraphql-subscriptionsgraphql-playgroundなど)の上に構築された便利なレイヤーであり、GraphQLサーバーを構築する最も簡単な方法です。

次の記事では、GraphQLリゾルバーに渡されるinfo引数の内部構造について説明します。

次の記事をお見逃しなく!

Prismaニュースレターに登録する