👨‍💻

C++BuilderでのRESTクライアントの使い方

2023/05/14に公開

はじめに

C++Builder(というかDelphi)にはDatasnapというクライアント/サーバアプリケーションのフレームワークがある。これを使うことで簡単に2つ以上のプログラムを連携させることができる。本記事ではサーバとクライアントを同一プログラム内に実装しているが、クライアント用のプロジェクトと分けても手順は変わらない。

RESTサーバの作成

RESTクライアントのテストをするため、まず先にRESTサーバを作成する手順を示す。

  • ファイル - 新規作成 - その他 - C++Builderプロジェクト - Datasnap - DatasnapRESTアプリケーション

  • デフォルトのまま

  • デフォルトのまま

  • デフォルトのまま

  • デフォルトのまま

  • デフォルトのまま

  • TDataModuleを選択

  • プロジェクトの保存先を指定

Datasnap RESTサーバ用のプロジェクトが配置されるため、次の節からRESTクライアント用のコードを書いていく。

RESTクライアントの作成

ここでは、先ほど作成したRESTサーバのプログラムに対してRESTクライアントの実装を行う。

コンポーネントの配置

プロジェクトに以下のコンポーネントを追加する。

  • TButton
  • TMemo
  • TRESTClient
  • TRESTRequest
  • TRESTResponse

同期実行

同期実行の場合、クライアントはExecuteメソッド実行後にサーバからの返答があるまで停止する。本サンプルは即時に反応が戻るが別PCやクラウドにサーバがある場合、アプリケーション自体が数秒固まる。
この間に次のリクエストが来ると処理待ちが発生したり、エラーになる(と思う)。

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	// コンポーネント同士の連携
	RESTRequest1->Client = RESTClient1;
	RESTRequest1->Response = RESTResponse1;
	
	// 接続先のURL (BaseURLにまとめて記載して、Resourceを使わないことも可能)
	RESTClient1->BaseURL = "http://localhost:8080/";
	RESTRequest1->Resource = "datasnap/rest/TServerMethods1/EchoString/abc";
	
	// メソッドタイプを指定
	RESTRequest1->Method = rmGET;
	
	// リクエストの発行
	RESTRequest1->Execute();    // サーバ側からの返答があるまで処理待ち
	Memo1->Lines->Add(RESTResponse1->JSONText);
}

非同期実行

ExecuteAsync関数を用いることで、サーバからの返答を待たずに処理を続けることができる。返答時の処理はExecuteAsync内の第1引数に無名関数で記載する。内部的にはスレッドで実行されているようだ。スレッドオブジェクトを自分で作成して、リクエストごとにnew-delete(体験談)する必要がなくなる。

void __fastcall TForm1::Button1Click(TObject *Sender)
{
	// コンポーネント同士の連携
	RESTRequest1->Client = RESTClient1;
	RESTRequest1->Response = RESTResponse1;
	
	// 接続先のURL
	RESTClient1->BaseURL = "http://localhost:8080/";
	RESTRequest1->Resource = "datasnap/rest/TServerMethods1/EchoString/abc";
	
	// メソッドタイプを指定
	RESTRequest1->Method = rmGET;
	
	// リクエストの発行 (サーバ側からの返答を待たずに処理が進む)
	// ただし、レスポンスが帰るまでClient/Requestのパラメータを変更してはいけない
	RESTRequest1->ExecuteAsync([=](){Memo1->Lines->Add(RESTResponse1-JSONText);},
		true,   // 上記の無名関数をメインスレッドで実行, falseの場合スレッドで実行
		true    // 実行終了後にスレッドオブジェクトを自動で解放
	);
}

アプリケーションの実行

  • Startボタンを押してサーバを起動する
  • Button1を押すと、送信した結果がMemo1に表示される

参考

https://docwiki.embarcadero.com/RADStudio/Alexandria/ja/DataSnap_REST
https://blogs.embarcadero.com/ja/lambda-expressions-for-beginners-ja/

Discussion