HTTPクラス: 非同期の HTTPリクエストを実行する新しい方法

4D のシンタックスと機能の改善に向けた弛まぬ努力の中で、4D で HTTPリクエストを実行するために、新しい HTTPRequest クラス を提供することに決定しました。このクラスは、4D v19 R6 で利用でき、今後のバージョンアップで多くの改良が加えられる予定です。さっそく、その使い方を紹介しましょう。

HDI: HTTPRequest クラス

シンプルなリクエスト

HTTPリクエストを送信するための基本シンタックスは、とてもシンプルです:

$request:=4D.HTTPRequest.new($url).wait()
If ($request.response#Null)
	// レスポンスを処理するコード
Else
	// エラーを処理するコード
End if

4D.HTTPRequest.new の呼び出しは、リクエストをインスタンス化し送信します。リクエストの結果は、HTTPRequest の response属性で取得されます。
さて、この中で wait がなぜ呼び出されているのか気になるところです。新しい HTTPRequest クラスは、非同期で使用されることを想定しています。リクエストを処理する専用プロセスを作成する必要はなく、メソッドの途中でリクエストを送信しても、メソッドの実行はブロックされません。しかし、もし同期的な振る舞いを維持したいのであれば、リクエスト完了を待つために wait を呼び出すことができます。

非同期リクエスト

次は、非同期でリクエストをおこなう方法をみていきましょう:

$request:=4D.HTTPRequest.new($url) 
// リクエスト完了前に実行されるコード

If ($request.terminated) // リクエストが完了している場合
	If ($request.response#Null)
		// レスポンスを処理するコード
	Else
		// エラーを処理するコード
	End if
End if

このとおり、とてもシンプルです。これで、リクエスト送信中にコードが実行でき、最適なパフォーマンスの恩恵を受けられるようになりました。

コールバックを使った非同期リクエスト

最後の例は、少し複雑になります。新しいシンタックスでは、コールバックを使ってリクエストを処理することができます。一般的には、HTTPリクエストを扱うための新しいクラスを作成します (この例ではクラス名: myClassToHandleHTTPRequests):

Class constructor()

Function onResponse($request : 4D.HTTPRequest)
// レスポンスを処理するコード

Function onError($request : 4D.HTTPRequest)
// エラーを処理するコード

そして、このクラスを使って自動的にリクエストを処理します:

$callbacks:=cs.myClassToHandleHTTPRequests.new()
$request:=4D.HTTPRequest.new($url; $callbacks)

メソッド内でリクエストを処理する必要はありません。レスポンスが利用可能になり次第、onResponse と onError コールバックによってリクエストの結果は処理されます。ここで、注意すべき点が一つあります: コールバックは呼び出しメソッドと同じプロセスで実行されることです。つまり、コールバックが呼び出される前にプロセスを終了してしまうと、リクエストの結果を取り逃がすことになります。メソッドの最後には、すべてのリクエストが完了したことを確認するようにしてください。

最後の例として、実際的なシナリオを見てみましょう。トリビアの REST API をリクエストし、ランダムな質問をユーザーに送信することにします。以下は、リクエスト処理用に作成する TriviaRequestClass クラスです:

Class constructor()

Function onResponse($request : 4D.HTTPRequest)
If ($request.response.status=200)
	ALERT("質問: "+String($request.response.body[0].question))
	ALERT("答え: "+String($request.response.body[0].answer))
Else 
	This.onError($request)
End if 

Function onError($request : 4D.HTTPRequest)
ALERT("質問のロード中にエラーがありました")

これを使い、リクエストを送信することができます。

$callbacks:=cs.TriviaRequestClass.new()
$request:=4D.HTTPRequest.new("http://jservice.io/api/random"; $callbacks)

ランダムなトリビアの質問に答えることを楽しんでください!

HDI の例題

フランスは今日もいい天気

この機能を説明するために、天気予報の RESTサービスに問い合わせる デモ をご用意しました。デモでは、フランスの天気予報を提供するための、これらの異なるリクエストの動作を確認することができます。

新しい HTTP 機能は今後もリリースされる予定ですので、このブログ記事は新しい HTTP クラスに関するシリーズ記事の最初の 1つとなります。

いつものように、もしコメントがありましたら 4Dフォーラムにお寄せください。

Nicolas Brachfogel
- プロダクトオーナー & シニアデベロッパー - Nicolas Brachfogelは、2017年にシニアデベロッパーとして4Dに入社しました(4D Serverとネットワークを担当)。Apple Siliconのリリースを管理するプロダクトオーナーとして、ユーザーストーリーを書いて機能仕様に落とし込み、機能実装が顧客のニーズを満たしているかを確認する役割を担っています。Institut Supérieur d'Informatique Appliquée (INSIA) を卒業した Nicolas は、2001年にソフトウェア開発者としてのキャリアをスタートさせました。JavaとC++で数年間コーディングした後、ゲーム会社のクライアント・サーバー開発を専門に担当。サーバー開発者/アーキテクトとして、多くのゲーム(Dofus Arena、Drakerz、Trivial Pursuit Go!)のサーバーアーキテクチャに携わり、成功を収めてきました。