チュートリアル:FireDAC RAD サーバー リソースを実装する
RAD サーバー リソースの概要 への移動
EMS パッケージを使用すると、FireDAC によりデータベースからリソースを公開できるようサーバーを拡張することができます。サーバーを拡張したら、EMS コンソール サーバーを使用してエンドポイント呼び出しのアナリティクスを確認できます。
EMS サーバーを拡張する独自の FireDAC API を作成するには、リソースを含む EMS パッケージを作成する必要があります。
概要とアーキテクチャ
このサンプルでは、Delphi EMS パッケージを作成し、FireDAC を使って InterBase データベースのデータを公開します。
リソースを新規作成するには:
- [ファイル|新規作成|その他...|新規作成]を開きます。
- 新しい EMS パッケージを作成するには:
- Delphi の場合:[Delphi プロジェクト|EMS|EMS パッケージ]。
- C++ の場合: [C++Builder プロジェクト|EMS|EMS パッケージ]。
- [リソースを含むパッケージを作成する]を選択し、[次へ >>]をクリックします。
- リソース名を入力します。たとえば「FireDACTest」などです。
- [データ モジュール]を選択して[次へ >>]をクリックします。
- [Get]と[Post]を選択し、[完了]をクリックします。
Unit1.dfm に以下のコンポーネントを追加します。
- データベースに接続するための 1 つの TFDConnection コンポーネント。
- 右クリックして[接続エディタ...]を開きます。
- [ドライバ ID]を[IB]に設定します。
- Database を
C:\Users\Public\Documents\Embarcadero\Studio\23.0\Samples\Data\EMPLOYEE.GDB
に設定します。 - User_Name と Password を「sysdba」と「masterkey」に設定します(デフォルトのパラメータを使用している場合)。
- 1 つの TFDPhysIBDriverLink コンポーネント。
- 1 つの TFDGUIxWaitCursor コンポーネント。
- 1 つの TFDStanStorageJSONLink コンポーネント。
- 1 つの TFDSchemaAdapter コンポーネント。
- 2 つの TFDQuery コンポーネント。
- ある TFDQuery を QEmployee に、他のものを QCustomer に名前変更します。
- Connection プロパティに先ほどの TFDConnection を選択します。
- SchemaAdapter プロパティのドロップダウン コンボ ボックスで先ほどの TFDSchemaAdapter を選択します。
- 右クリックして[クエリ エディタ...]を開きます。
- SQL コマンドを入力します:
- QEmployee コンポーネントで:Select * from employee
- QCustomer コンポーネントで: Select * from customer。
- CachedUpdates プロパティを
True
.に設定します。
- 2 つの TDataSource コンポーネント。
- ある TDataSource を DEmployee に、他のものを DCustomer に名前変更します。
- DataSet プロパティで、対応するクエリを選択します。
[コード]タブで以下のコードを記述します:
- Delphi の場合:
published
[EndpointName('GetRecords')] // Name of the call to show in the analytics.
procedure Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
[EndpointName('PostUpdates')] // Name of the call to show in the analytics.
procedure Post(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
- C++ の場合(Unit1.cpp ファイル内):
void __fastcall PACKAGE Register()
{
std::auto_ptr<TEMSResourceAttributes> attributes(new TEMSResourceAttributes());
attributes->ResourceName = "FireDACTest";
attributes->EndPointName["Get"] = "GetRecords";
attributes->EndPointName["Post"] = "PostUpdates";
RegisterResource(__typeinfo(TFireDACTestResource1), attributes.release());
}
Get 手続きのコードを記述します:
- Delphi の場合:
procedure TFireDACTestResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
var
oStr: TMemoryStream;
begin
oStr := TMemoryStream.Create;
try
QEmployee.Open;
QCustomer.Open;
FDSchemaAdapter1.SaveToStream(oStr, TFDStorageFormat.sfJSON);
// Response owns stream
AResponse.Body.SetStream(oStr, 'application/json', True);
except
oStr.Free;
raise;
end;
end;
- C++ の場合(Unit1.cpp ファイル内):
void TFireDACTestResource1::Get(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) {
std::auto_ptr<TMemoryStream> oStr(new TMemoryStream());
QEmployee->Open();
QCustomer->Open();
FDSchemaAdapter1->SaveToStream(oStr.get(), TFDStorageFormat::sfJSON);
AResponse->Body->SetStream(oStr.release(), "application/json", true);
}
Post 手続きのコードを記述します:
- Delphi の場合:
procedure TFireDACTestResource1.Post(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
var
LStream: TStream;
begin
if not SameText(ARequest.Body.ContentType, 'application/json') then
AResponse.RaiseBadRequest('content type');
if not ARequest.Body.TryGetStream(LStream) then
AResponse.RaiseBadRequest('no stream');
LStream.Position := 0;
FDSchemaAdapter1.LoadFromStream(LStream, TFDStorageFormat.sfJSON);
FDSchemaAdapter1.ApplyUpdates
end;
- C++ の場合(Unit1.cpp ファイル内):
void TFireDACTestResource1::Post(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) {
TStream* LStream;
if (!(SameText(ARequest->Body->ContentType, "application/json")))
AResponse->RaiseBadRequest("content type");
if (!(ARequest->Body->TryGetStream(LStream)))
AResponse->RaiseBadRequest("no stream");
LStream->Position = 0;
FDSchemaAdapter1->LoadFromStream(LStream, TFDStorageFormat::sfJSON);
FDSchemaAdapter1->ApplyUpdates();
}
- C++ でのみ: 次のコンポーネントのパッケージとその下位オブジェクトを、Requires ノードに追加します:
- プロジェクト マネージャで、[必須] ノードを右クリックします。
- [参照を追加...]を選択します。
- [検索パス]フィールドを次のように設定します:
C:\Program Files (x86)\Embarcadero\Studio\23.0\lib\win32\release
- [パッケージ名]フィールドで次のパッケージを追加します:
FireDACCommonDriver.bpi FireDACCommon.bpi FireDAC.bpi FireDACIBDriver.bpi
新規リソースのテスト
開発環境でプロジェクトをテストするには:
- [実行|実行時引数...]を選択します。
- [ホスト アプリケーション]フィールドの EMS サーバー実行可能ファイルのパスが正しいことを確認します。パスは
C:\Program Files (x86)\Embarcadero\Studio\23.0\bin\EMSDevServer.exe
です。 - [実行|デバッガを使わずに実行]を選択してプロジェクトを実行します。
- サーバー ウィンドウが開きます。[ブラウザを開く]をクリックして、通常のブラウザでサーバーを開きます。
- メモ: プロジェクトに必要な変更を加えるためのウィンドウが表示されます。[OK]をクリックしてください。
サーバーを実行するのが初めてであれば、開発環境の実行の手順で、IB ファイルと構成ファイルを作成する必要があります。
次の URL をブラウザに入力します。
http://localhost:8080/FireDACTest/ //It shows the defined queries as JSON data.
結果は次のようになります。
{"FDBS":{"Version":14,"Manager":{"UpdatesRegistry":true,"TableList":[{"class":"Table","Name":"QEmployee","SourceName":"employee","SourceID":1,"TabID":0,"EnforceConstraints":false,"MinimumCapacity":50,"ColumnList":[{"class":"Column","Name":"EMP_NO","SourceName":"EMP_NO","SourceID":1,"DataType":"Int16","Searchable":true,"Base":true,"OInUpdate":true,"OInWhere":true,"OInKey":true,"OriginTabName":"EMPLOYEE","OriginColName":"EMP_NO"},{"class":"Column","Name":"FIRST_NAME","SourceName":"FIRST_NAME","SourceID":2,"DataType":"AnsiString","Size":15,"Searchable":true,"Base":true,"OInUpdate":true,"OInWhere":true,"OriginTabName":"EMPLOYEE","OriginColName":"FIRST_NAME","SourceSize":15},{"class":"Column","Name":"LAST_NAME","SourceName":"LAST_NAME","SourceID":3,"DataType":"AnsiString","Size":20,"Searchable":true,"Base":true,"OInUpdate":true,"OInWhere":true,"OriginTabName":"EMPLOYEE","OriginColName":"LAST_NAME","SourceSize":20},{"class":"Column","Name":"PHONE_EXT","SourceName":"PHONE_EXT","SourceID":4,"DataType":"AnsiString","Size":4,"Searchable":true,"AllowNull":true,"Base":true,"OAllowNull":true,"OInUpdate":true,"OInWhere":true,"OriginTabName":"EMPLOYEE","OriginColName":"PHONE_EXT","SourceSize":4},{"class":"Column","Name":"HIRE_DATE","SourceName":"HIRE_DATE","SourceID":5,"DataType":"DateTimeStamp","Searchable":true,"Base":true,"OInUpdate":true,"OInWhere":true,"OriginTabName":"EMPLOYEE","OriginColName":"HIRE_DATE"},
...
また、コンソールには 'GetRecords' エンドポイントが呼び出されたことが表示されます。詳細は、「EMS コンソール サーバーのセットアップ」を参照してください。