1
/
5

Restful API、GraphQL…フロントエンドとバックエンドをつなげる方法

Webアプリケーション開発時に、フロントエンドとバックエンドを分かれて開発するのはよくあるケースです。そうやって分業で開発されるフロントエンドとバックエンドはどう連携し合うのが良いでしょうか。

この記事はよくあるケースを幾つか紹介します。

RESTful API

RESTとはRepresentational State Transferの略になります。RESTの原則に従って開発されるシステムをRESTfulと言い、そのAPIをRESTful APIと呼びます。

RESTful APIでは、URIとHTTPメソッドの組み合わせによって、何のリソースをどう処理するかを指定します。HTTPメソッドは次のような意味で用います。

HTTPメソッド意味GETリソースの取得POSTリソースの作成PUT/PATCHリソースの更新DELETEリソースの削除

それに対してURIでは、どのリソースを操作するかを指定します。例として以下のようになります。

  • ユーザーに対する操作(作成または一覧取得)/users
  • に対する操作(更新または削除)/users/:userId
    ユーザーID =:userId
  • アイテムに対する操作(作成または一覧取得)/items
  • に対する操作(更新または削除)/items/:itemId
    アイテムID =:itemId
  • なユーザーが所有するアイテムに対する操作(作成または一覧取得)/users/:userId/items
    ユーザーID =:userId
  • に対する操作(更新または削除)/users/:userId/items/:itemId
    ユーザーID =:userId
    なユーザーが所有するアイテム:itemId

そしてHTTPメソッドとURIを並べてAPIを表現します。例えば以下のように書きます。

  • POST /users
    ユーザ作成
  • の取得GET /users/:userId
    ユーザID =:userId
  • の更新PATCH /users/:userId/items/:itemId
    ユーザID =:userId
    のユーザーが持つアイテム:itemId

RESTful APIの利点

URIを見ればどのリソースを対象にしているか分かり、HTTPメソッドを見ればどういった操作を行うかが分かります。

RESTful APIの欠点

URI(エンドポイント)が分かっていないとAPI操作ができません。また、分かりやすさのためにRESTful原則に反したURIが作成される場合があります。

例)

  • アイテム検索/items/search
  • ログイン/login

返ってくるデータ(レスポンス)の詳細をクライアント側で制御するのはあまり現実的ではありません。例えばクエリーパラメータで指定したり、別なAPIを作成する必要があります。レスポンスが複雑になればなるほど、この制御は困難になります。

  • クエリーパラメータで制御する例
    GET /users/:userId?fields=name,email,profile
  • APIを分ける例GET /users/:userId
    GET /users/:userId/more_fields

GraphQL

エンドポイントが分からないとアクセスできない、送受信されるデータの形がドキュメントを見ないと分からないといったRESTful APIの難点を解決すべく作られたのがGraphQLです。元々はFacebookが自社APIで使っていたFQL(Facebook Query Language)になります。このFQLを汎用化したものがGraphQLになります。

GraphQL | A query language for your API

GraphQLの利点

以下がGraphQLの利点になります。

  1. エンドポイント/HTTPメソッドが1つである
  2. スキーマが用意されている
  3. 取得するデータをクライアントが指定できる

エンドポイント/HTTPメソッドが1つである

とします。すべてのリソースへのアクセスは、この1つのエンドポイントだけで行います。また、アクセスはすべてPOSTメソッドになります(取得、更新、削除すべて)。この点はとても分かりやすいです。GraphQLは一般的にエンドポイントを/graphql

スキーマが用意されている

スキーマとはリクエストや、取得されるデータの形式を定義したドキュメントになります。このスキーマがAPIの1つとして公開されていることで、各プログラミング言語で読み込んだり、プレイグラウンド(テスト実行環境)で自動補完の恩恵に預かれます。

HexabaseのPlaygroundの例

取得するデータをクライアントが指定できる

最後に、取得するデータをクライアント側で細かく指定できる点もGraphQLの特徴です。例えば以下のように記述します。これはユーザーデータを取得しますが、名前とメールアドレスが欲しい場合です。

query users {
	name
	email
}

Copy

上記に加えて、年齢が欲しい場合には次のように記述します。

query users {
	name
	email
	age
}

Copy

さらにユーザーに紐付いた商品情報が欲しい場合もあるでしょう。その場合には、以下のように指定します。

query users {
	name
	email
	age
	items {
		id
		name
		price
	}
}

Copy

このようにクライアント側からGraphQLの内容を指定することで、そのレスポンスを動的に変更できます。必要な場面に応じて、リクエスト内容を変更することで、必要なデータだけを取得できます。

GraphQLの欠点

逆に欠点としては、技術的にまだ広く浸透しているとは言いがたく、ナレッジがたまっていないことでしょう。何か困ったことがあっても、オンライン上で即座に答えが見つからないかも知れません。

また、ライブラリがまだ多くないのも難点です。例えばJavaScriptであればApollo GraphQLというライブラリが有名です。他の言語でもGraphQLクライアントがありますが、ほぼ素のGraphQLを記述しなければならない点が難点です。

gRPC

gRPCのWebサイト

RPCというのはRemote Procedure Callの略になります。そしてgRPCというのはGoogleが開発、公開したRPCになります。RPCを簡単に言うと、クライアントからサーバー側のメソッドを指定して実行する技術になります。gRPC登場以前にはXML-RPCやJSON-RPCがありましたが、これらはテキストデータを扱うのに特化していました。例えばWordPressではXML-RPCが利用できましたが、画像アップデートはバイナリファイルをテキスト変換(Base64エンコード)して行っています。

XML-RPC wp « WordPress Codex

gRPCはそれらの難点を解決し、バイナリデータでも扱えるRPCとなっています。

gRPCの特徴

gRPCはXML-PRCやJSON-RPCと異なり、HTTP/HTTPSは利用しません。HTTP/2を使い、データフォーマットはProtocol Buffersを基本としています。ただ、仕様上これらは自由に選択できるようです。

Protocol Buffersはプロトコル定義ファイルを用意します。これはクライアント・サーバー間でやり取りされるデータの定義ファイルになります。そして、このプロトコル定義ファイルを利用して、各種プログラミング言語向けにクラスファイルが生成できます。このクラスファイルを利用することで、クライアント側での開発はとても楽になるでしょう。

同様にサーバー側のサービスについて、サービス定義ファイルも作成します。これによってクライアント側では、サーバー側の呼び出せる機能と、その呼び出し方が分かります。このサービス定義ファイルを使うことで、サーバー側とクライアント側のコードも生成可能です。

Webでの利用

Webアプリケーションの中でgRPCを使う場合にはgrpc/grpc-web: gRPC for Web Clientsを利用します。ただし、素のgRPCと比べて幾分制限があるようなので注意してください(筆者は使ったことがありません)。

一般的にはgRPCはサーバー間通信などで利用するのが便利かと思います。

WebSocket

ブラウザとサーバーで同期通信を行いたい場合にはWebSocketが便利です。ブラウザからサーバーへの送信はもちろん、サーバーからブラウザへメッセージの送信もできます。なお、WebSocketはテキストメッセージのみ送受信可能です。JSONを使う場合には一旦文字列に変換して、受け取った後にパースします。

WebSocketではURIを使って、どのチャンネルを購読(Subscribe)するか指定します。サーバー側では、この購読しているクライアントだけにメッセージを送信することで、例えばチャットルームなどの配信先を限定したメッセージ送信を行えます。

というオブジェクトを使います。JavaScriptではWebSocket

const ws = new WebSocket('wss://localhost:4000/websocket');

Copy

イベントが実行されます。接続されるとonopen

ws.onopen = function() {
	// 接続された際のイベント
}

Copy

を使います。次にメッセージを送る際にはsend

ws.send(JSON.stringify({message: "新しいメッセージ"}));

Copy

イベントに処理を書きます。メッセージを受け取る際にはonmessage

ws.onmessage = function(message) {
	// ここに処理を書きます
}

Copy

イベントが呼ばれます。接続を閉じた際にはonclose

ws.onclose = function() {

}

Copy

サーバーからブラウザに対して何かメッセージを送りたい時に試してください。

Web Push API

サーバーからのメッセージが非同期でも良い場合にはWeb Push APIを利用することもできます。2023年中にはmacOS/iOS/Android/Windows/Linuxと幅広いOS、Webブラウザでサポートされます。2022年7月現在ではiOSでは利用できません(macOSはSafariでは利用できません)。

Push API | Can I use… Support tables for HTML5, CSS3, etc

Web Push APIではユーザーの承認が必要です。プッシュ通知送信に関する承認が得られると、固有のURIが得られます。これは各ブラウザベンダー毎に異なるもので、例えばChromeの場合はFirebaseのドメインで、デバイストークン(ブラウザ固有のID)を含んだものになります。

サーバー側ではこの固有のURIを保存します。そしてプッシュ通知を送信する際に、このURIに対して送信したいメッセージと共にリクエストを送信します。

ブラウザがメッセージを受け取ると、Service Workerのpushイベントが呼ばれます。

self.addEventListener('push', function(event) {
	// このイベントが呼ばれます
});

Copy

この中で通知オブジェクトを作り、表示を行います。同時に、この通知をクリックした際のイベントを設定し、特定のURLに遷移したりします。

data = event.data.json();
const title =  data.title;
const body = data.message;
const icon = data.icon;
const tag = 'タグ';
const notification = new Notification(title, {
	body, icon, tag,
});

notification.addEventListener('click', function() {
	if (clients.openWindow) {
		clients.openWindow('https://example.com/click.html');
	}
});

Copy

まとめ

クライアントからサーバー側の処理を呼び出す場合と、サーバー側からクライアントを呼び出す場合で利用できる技術が変わります。ぜひ最適なものを選んでください。個人的に試したことはないのですが、GraphQLにはSubscriptionが用意されており、データが更新されると通知してくれる機能もあるようです(実装系によるとは思います)。

私たちの提供するHexabaseではRESTful APIWebSocketGraphQL(現在アルファ版)を用意しています。アプリの特性、開発要件に合わせて選択してください。

役に立ったら、記事をシェアしてください

株式会社Hexabaseでは一緒に働く仲間を募集しています

同じタグの記事

今週のランキング