この記事は David I (David Intersimone) によるIntroduction to Building Your First RAD Server Serviceの抄訳です。

目次

  1. RAD Serverプロジェクトウィザードを使用する
  2. ウィザードが生成したRAD Serverプロジェクトとソースコードを確認する
  3. 初めてのRAD Serverアプリケーションを設定する
  4. 初めてのRAD Serverアプリケーションのテスト
  5. 参考情報

このブログ記事では、DelphiとC++Builderを使って最初のRAD Serverサービスベースのアプリケーションを構築する方法を学びます。開発を始める前に、InterBaseデータベースサーバーが稼働していることを確認してください。 RAD Serverは、ユーザー情報、ユーザーグループ、アナリティクス、登録済みデバイス、バージョン情報、登録済みエッジモジュール、プッシュ通知メッセージなどの保存にInterBaseデータベースを使用します。


図1: InterBase 2017 サーバーマネージャー

InterBase が見当たらない場合はインストールとサーバの起動を済ませてから先に進んでください。ESDインストーラの場合は IDE の[ツール]メニューから[プラットフォームの管理]よりインストールできます。ISOインストーラの場合はインストーラを再度実行してください。

1.RAD Serverプロジェクトウィザードを使用する

RAD Server 向けのプロジェクトを手早く作成する方法は RAD Studio / Delphi / C++Builder用のRAD Serverパッケージウィザードを実行することです。新規プロジェクトの作成メニュー([ファイル]⇒[新規作成]⇒[その他])より [RAD Server] の [RAD Serve パッケージ] を選択します。


図2:Delphi / C++Builder 向けプロジェクト新規作成画面

RAD Server パッケージプロジェクトを選択すると、新規プロジェクト作成のためのウィザードが起動します。最初の画面ではRAD Serverアプリケーションに設定するリソース名とエンドポイントを作成する方法を指定します。ここでは2つの方法のいずれかを選択します。

選択肢1:リソースを登録しない方法「空のパッケージを作成する」を選択します。

後でリソースをご自身でコードで実装する場合は、このオプションを選択してください。この選択ではメインライブラリだけを持つパッケージプロジェクトが作成されます。


図3:「空のパッケージを作成する」

[完了]ボタンをクリックすると、追加の開発作業用の開始プロジェクトが作成され、完成したRAD ServerアプリケーションがIDEで開きます。

選択肢2:RAD Server用のREST APIを拡張する方法「リソースを含むパッケージを作成する」を選びます。

[次へ]ボタンをクリックすると、パッケージプロジェクト、リソース、およびエンドポイントの作成に役立つ2つの追加のウィザード画面が表示されます。

RAD Serverプロジェクトをはじめて構築する場合は、こちらを選びます。


図4:「リソースを含むパッケージを作成する」を選択する

ウィザードの2ページ目で、リソース名を “test”に設定します。ラジオボタン[ファイルの種類]には、2つの選択肢がありますが、初めての RAD Server アプリケーション開発では、データモジュールを選択します。

選択肢 必要な実装
データモジュール データモジュールにIDEのデザイナでコンポーネントを配置し、コードエディタでリソースを構築する
ユニット コンポーネントを使用せず、リソースを構築するためコードをユニットに実装する


図5:RAD Serverパッケージウィザード 2ページ目 - リソース名とファイルの種類を設定する

[次へ]ボタンをクリックし、作成するエンドポイントを選択します。


図6:RAD Serverパッケージウィザードページ3 - 機能を実装するエンドポイントを選択

ウィザードの3ページ目では、一連の定義済みエンドポイントから使用するものを選択します。それぞれ次の機能が実装できます。

エンドポイント 機能
Get (REST GET)
GetItem (URLの末尾に取得する項目を識別するセグメントを持つREST GET)
Post (REST Post)
PutItem (REST Put) URLの末尾に配置するアイテムを識別するセグメントを指定
DeleteItem (削除するアイテムを識別するURLの末尾にセグメントを指定してREST Delete)

すべてのエンドポイントを実装する場合は[EndPoint]リストの下部にある[すべて選択/選択解除]チェックボックスも利用できます。また、ウィザードの前のページに戻ったり、ステップリンクをクリックして、パッケージ、リソース、およびエンドポイントを変更することもできます。指定した設定内容でプロジェクトを作成するには、[完了]ボタンをクリックします。ウィザードが完了するとIDEに戻ります。

それでは、まず最初にプロジェクトに名前をつけて保存しましょう。C++およびDelphiデータモジュールには、「MyDMUnit」という名前をつけます。C++プロジェクトとパッケージには「MyFirstCppRADServerPackage」という名前をつけます。Delphiプロジェクトとパッケージには「MyFirstDelphiRADServerPackage」という名前をつけます。

2. ウィザードが生成したRAD Serverプロジェクトとソースコードを確認する

Delphi / C++ のウィザードが作成したプロジェクトとソースコードは以下のとおりです。

C++コードでは、レスポンスを設定するためにGetおよびGetItemエンドポイント実装に数行のコードを追加しています(MyDMUnit.cppで // サンプルコード と明示されている箇所を確認してください)。

Delphi


図7:生成されたDelphiプロジェクト


図8:生成されたDelphiリソースモジュール

MyFirstDelphiRADServerPackage.pas

package MyFirstDelphiRADServerPackage;

{$R *.res}
{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO OFF}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES ON}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$DEFINE DEBUG}
{$ENDIF IMPLICITBUILDING}
{$RUNONLY}
{$IMPLICITBUILD ON}

requires
  rtl,
  emsserverapi;

contains
  MyDMUnit in 'MyDMUnit.pas' {TestResource1: TDataModule};

end.

MyDMUnit.pas

unit MyDMUnit;

// EMS Resource Module

interface

uses
  System.SysUtils, System.Classes, System.JSON,
  EMS.Services, EMS.ResourceAPI, EMS.ResourceTypes;

type
  [ResourceName('test')]
  TTestResource1 = class(TDataModule)
  published
    procedure Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
    [ResourceSuffix('{item}')]
    procedure GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
  end;

implementation

{%CLASSGROUP 'System.Classes.TPersistent'}

{$R *.dfm}

procedure TTestResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
begin
  // Sample code
  AResponse.Body.SetValue(TJSONString.Create('test'), True)
end;

procedure TTestResource1.GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
var
  LItem: string;
begin
  LItem := ARequest.Params.Values['item'];
  // Sample code
  AResponse.Body.SetValue(TJSONString.Create('test ' + LItem), True)
end;

procedure Register;
begin
  RegisterResource(TypeInfo(TTestResource1));
end;

initialization
  Register;
end.

C++


図9:生成されたC++プロジェクト


図10:生成されたC++リソースモジュール

MyFirstCppRADServerPackage.cpp

// EMS パッケージ
//---------------------------------------------------------------------------

#include <System.hpp>
#pragma hdrstop
USEFORM("MyDMUnit.cpp", TestResource1); /* TDataModule: File Type */
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------

// パッケージ ソース。
//---------------------------------------------------------------------------

#pragma argsused
extern "C" int _libmain(unsigned long reason)
{
    return 1;
}
//---------------------------------------------------------------------------

MyDMUnit.h


// EMS リソース モジュール
//---------------------------------------------------------------------------

#ifndef MyDMUnitH
#define MyDMUnitH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <System.SysUtils.hpp>
#include <EMS.Services.hpp>
#include <EMS.ResourceAPI.hpp>
#include <EMS.ResourceTypes.hpp>
//---------------------------------------------------------------------------
#pragma explicit_rtti methods (public)
class TTestResource1 : public TDataModule
{
__published:
private:
public:
 __fastcall TTestResource1(TComponent* Owner);
    void Get(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse);
    void GetItem(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse);
};
#endif

MyDMUnit.cpp


//---------------------------------------------------------------------------
#pragma hdrstop

#include "MyDMUnit.h"
#include <memory>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma classgroup "System.Classes.TPersistent"
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
__fastcall TTestResource1::TTestResource1(TComponent* Owner)
 : TDataModule(Owner)
{
}

void TTestResource1::Get(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse)
{
    // サンプルコード
    // "test" という固定の文字列で JSONString 型を作って SetValue で返す
    AResponse->Body->SetValue(new TJSONString("test"), true);
}

void TTestResource1::GetItem(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse)
{
     String item;
     item = ARequest->Params->Values["item"];

    // サンプルコード
    // "test" + item という可変文字列で JSONString 型を作って SetValue で返す
    AResponse->Body->SetValue(new TJSONString("test " + item), true);
}

static void Register()
{
    std::auto_ptr<TEMSResourceAttributes> attributes(new TEMSResourceAttributes());
    attributes->ResourceName = "test";
    attributes->ResourceSuffix["GetItem"] = "{item}";
    RegisterResource(__typeinfo(TTestResource1), attributes.release());
}

#pragma startup Register 32Ts

3. 初めてのRAD Serverアプリケーションを設定する

初めてのRAD Serverアプリケーションをウィザードで作成したら、IDEからのコンパイルやテストが行えます。

開発環境ではIDEがRAD Server開発サーバ (EMSDevServer.exe) をホストアプリケーションとして使用します。ロードするパッケージファイルはパラメータで指定して実行されます。EMSDevServerにはWin32とWin64用の2つのバージョンがあります($(BDS)\bin\EMSDevServer.exe と $(BDS)\bin64\EMSDevServer.exe)


図 11: プロジェクトのオプションでは、デバッガのホストアプリケーションとしてEMSDevServer.exeが設定されている

Delphi / C++Builder / RAD Studioには、開発環境で RAD Server コンソールの機能を確認できるRAD Server 開発コンソール(EMSDevConsole.exe)も含まれます。EMSコンソールは、作成したRAD Serverアプリケーションに関するアナリティクス情報の表示やユーザー/グループの管理などの機能をWebアプリケーションとして提供します。

RAD Server 開発サーバはIDEからプロジェクトをビルドして実行できます。メニューから実行を選ぶか、またはF9 キーを押すとアプリケーションのコンパイルとリンクの後、RAD Server 開発サーバが実行されます。RAD Server 開発コンソールは RAD Server 開発サーバの画面から起動できます。

RAD Server 開発サーバは、デフォルトでTCPポート8080を使用して起動します。またRAD Server開発コンソールは、TCPポート8081を使用します。なお、初めてRAD Serverアプリケーションを実行しようとした場合は「EMS サーバ構成ファイルが見つかりません」というダイアログボックスが表示されます。(このメッセージはRAD Server関連のレジストリ設定がない場合や、設定ファイルが存在しない場合にも表示されます。)


図12:設定ファイルなしでRAD Server 開発サーバを起動した場合

ここでは[はい]ボタンをクリックして、RAD Server設定ウィザードを実行します。


図13:RAD Serverセットアップウィザード ページ1 - 新しいEMSデータベース接続パラメータの指定

ウィザードの最初の手順で、InterBaseサーバーインスタンスを入力します(デフォルトでは、RAD Studioの開発バージョンのInterBase Serverはgds_dbを使用します)。
以前に別のサーバーインスタンス名を使用してInterBaseをインストールした場合は、その名前文字列を入力します。

このウィザードの画面には、RAD Serverデータベースの名前(emsserver.ib)、およびデータベースと構成ファイルを格納するディレクトリも含まれています。

[次へ]ボタンをクリックして次の画面に進むと、ユーザーおよびユーザーグループ用のサンプルRAD Serverデータベースデータを作成するかどうかをチェックボックスで表示する画面が表示されます。

開発とテストのために、両方のチェックボックスを選択してサンプルデータの生成を行います。


図14:RAD Serverセットアップウィザードの2ページ目 - データベース用のサンプルデータの生成を選択

[次へ]をクリックして次の画面に進むと、RAD Serverコンソールにログインするためのユーザー名とパスワードの設定画面が開きます。


図15:RAD Serverセットアップウィザードページ2 - コンソールのユーザー名とパスワードを選択します

[次へ]ボタンをクリックしてウィザードの最後の画面に進むと確認画面が表示され、RAD Serverデータベースファイルや設定ファイル、ログインユーザのレジストリキーに設定されるパスが表示されています。


図16:RAD Server設定ウィザードの確認画面

RAD Server の動作に関する設定変更を行う場合は、構成ファイル (emsserver.ini) でを編集します。

完了ボタンをクリックすると開発環境では次の確認ダイアログが表示されます。開発環境でのRAD Serverでは内部データベースとしてライセンスを持たないInterBaseのインスタンスが使用されることを通知しています。

なお、開発環境では、RAD Serverアプリケーションの利用は最大5ユーザーに制限されています。


図17:確認ダイアログボックス - RAD ServerライセンスなしでInterBaseインスタンスを使用

開発環境ではなく本番環境にRAD Serverアプリケーションをデプロイする場合は、RAD ServerとInterBaseに配置ライセンスを使用できます。

ここで[はい]ボタンをクリックして先に進むとRAD Server設定ファイルの生成先パスや内部データベースに追加されたユーザ情報などのサンプルデータの情報が通知されます。


図18:設定ウィザードによって作成されたRAD Serverファイルのリスト

OKボタンをクリックするとウィザードはすべて終了します。

このウィザードで生成された2つのファイルが C:\Users\Public\Documents\Embarcadero\EMS あることを確認してください。


図19:RAD Server構成ウィザードによって作成された設定ファイル

このデータベース EMSSERVER.IB はInterBaseのIBConsoleプログラムで内容を表示できます。


図20:emsserver.ibデータベースファイルのIBConsoleビュー

またRegEditを使用して、RAD Server設定ファイルの場所用に作成されたレジストリキーを確認します。


図21: RAD Server 設定ファイルに関するレジストリキー

4. 初めてのRAD Serverアプリケーションのテスト

RAD Server構成サーバーが作成されると、RAD Server 開発サーバが実行を開始します。しかし開発環境によっては「ソケットをバインドできませんでした。アドレスとポートは既に使われています」というエラーメッセージが表示されることがあります。これは他のアプリケーション(Tomcatサーバー、他のWebサーバー、または他の実行中のアプリケーション)がすでにポート8080を使用しているためです。


図22:デフォルトのポートがすでに使用されているため、RAD Serverアプリケーションを起動できません。

これを解決するには、一旦 OKボタンをクリックし、RAD Server 開発サーバの画面からポート番号を変更します。


図23:ポートの競合のためにRAD Server 管理サーバが起動しないので、使用するポートを変更する

ここではポート番号を一時的に8087に変更してみます。ポート番号を変更したら[起動]ボタンをクリックします。指定されたポート番号が利用可能な場合はRAD Server 開発サーバが問題なく開始されます。

なお、ポート番号を一時的に変更するのではなく、常に別のポート番号を割り当てたい場合は、RAD Serverの設定ファイル emsserver.ini の下記の箇所を編集します。

[Server.Connection.Dev]
Port=8087

設定変更後、IDEからプロジェクトを実行すると、RAD Server 開発サーバは新しい設定で実行を開始します。ログにはパッケージアプリケーションに対して行われた操作が表示されます。

C++ Version:


図24: RAD Server 開発サーバで最初のC++アプリケーションパッケージを起動する
Delphi Version:


図25: RAD Server 開発サーバで最初のDelphiアプリケーションパッケージを起動する

RAD Server 開発サーバのログには、設定、データベース接続、ライセンス情報、ロードされたアプリケーションパッケージ、登録されたリソース、および作成されたエンドポイントが表示されます。

[ブラウザを開く]ボタンをクリックすると、デフォルトのブラウザが起動し、RAD Server標準の組み込みエンドポイント GetVersion を呼び出した結果が JSON で表示されます。

これで RAD Server の REST エンドポイントを初めて利用したことになります。


図26:ブラウザでバージョンのエンドポイントからの応答を表示

ブラウザのURLを localhost:8080/test に変更してみると、このエンドポイントからは次のJSONデータが返されます。


図27:ブラウザで test リソースの Get メソッドからの JSON を表示

URLにパラメータを追加すると、今度はGetItemエンドポイントが呼び出され、リソース名と入力した項目を含むJSON文字列が返されます。


図28:ブラウザで testリソースのGetItemメソッドからのJSON出力を表示

このようなシンプルな例ではJSON文字列をそのまま返しても大丈夫ですが、もっと大きく複雑なデータ構造ではあまり大きなJSON文字列を返さない方がいいかもしれません。

RAD Studioには、JSONオブジェクト、JSONストリーム、およびJSONライターの使用など、JSONデータを生成するための他の多くの方法があります。

さらにURLを “users” に書き換えてデフォルトのGetUsersエンドポイントを呼び出すと、RAD Server設定ウィザードによって生成され、RAD Serverのデータストア内に保存されているユーザーの情報がJSONで表示されます(初めて RAD Server 開発サーバを起動した場合は1件だけ表示されます)。


図29:ブラウザからのGetUsersエンドポイントへの呼び出しに対するJSON出力を表示

この出力は文字列がユニコードエスケープ形式のため若干読みづらいのですが、アプリケーションコードが扱う分には特に支障はありません。なお、ブラウザにJSONを整形表示する拡張機能を追加すれば次のように読める形式で表示されます。


図30:Google Chrome に拡張機能 JSONView をインストールしてJSON出力の表示を整形

これで、RAD Serverプロジェクトウィザードで生成されたエンドポイントやRAD Serverに標準で組み込まれているエンドポイントを使ってみることができました。

5. 参考情報

docwiki: RAD Server(EMS)
docwiki: RAD サーバー エンジンのセットアップ
docwiki: Windows での RAD サーバー エンジンまたは RAD サーバー コンソールの構成