RAD サーバー リソースの概要
RAD サーバー エンジンの拡張 への移動
EMS リソースは、EMS サーバー API を拡張するものです。
EMS リソースを EMS サーバーに読み込むと、EMS サーバーはそれを登録し、そのすべてのエンドポイントを公開します。EMS クライアント アプリケーションは、TBackendEndpoint コンポーネントを使って、EMS リソースのエンドポイントにアクセスすることができます。
- メモ: EMS リソースを定義する前に、その定義を含める EMS パッケージを作成してください。
目次
リソース クラスの定義
リソース クラスとは、EMS リソースを表すクラスです。
リソース クラスの宣言
リソース クラスは通常のクラスとして宣言することができます。以下に例を示します。
Delphi の場合:
TMyResource = class;
C++ の場合:
// .h
class TMyResource {};
リソース クラスには、以下のいずれかに該当する少なくとも 1 つのコンストラクタが必要です。
- パラメータのないコンストラクタ
- TComponent 型の 1 つのパラメータを受け取るコンストラクタ
リソース名
EMS リソースごとに、そのリソースを一意に識別するリソース名があります。EMS クライアント アプリケーションからリソースにアクセスするには、TBackendEndpoint コンポーネントの Resource プロパティに対象リソースの名前を設定する必要があります。
デフォルトでは、クラスが表す EMS リソースの名前は、クラス名からプレフィックスの "T" を取り除いたもの(付いていれば)です。たとえば、上記クラスのリソース名は "MyResource" になります。EMS リソースに異なる名前を付けたい場合は、後でカスタマイズすることができます。
エンドポイント メソッドの定義
リソース クラスを定義したら、次に、そのクラスにエンドポイント メソッドを追加します。
エンドポイント メソッドとは、そのメソッドが定義されたリソースに対する API 要求を処理するメソッドです。
API 要求では、"GET" などの要求メソッド(必須)と、リソース サフィックス(任意)を指定します。リソース クラスの各エンドポイント メソッドは、要求メソッドとリソース サフィックスの 1 つの組み合わせを処理するものでなければなりません。
エンドポイント メソッドで処理可能な要求を EMS サーバーが受け取ると、以下の処理が行われます。
- EMS サーバーがエンドポイント メソッドを実行します。
- エンドポイント メソッドが応答を生成します。
- 生成された応答を、EMS サーバーが、元の要求を送信したクライアント アプリケーションに送り返します。
エンドポイント メソッドの宣言
エンドポイント メソッドを宣言するには、以下の要件を満たすメソッドをリソース クラス内に宣言しなければなりません。
- public または published の可視性で宣言されている
- 要求メソッドの名前(
Get
、Put
、Post
、Delete
、Patch
)と一致する文字列で名前が始まっているGet
、PutItem
、PostWhateverYouWant
は、いずれもエンドポイント メソッド名として有効です。プレフィックスの大文字/小文字はどちらでもかまいません。たとえばGet
、get
、GET
はどれも、エンドポイント メソッド名の有効なプレフィックスです。
- シグネチャは、戻り値を持たず、TEndpointContext、TEndpointRequest、TEndpointResponse の 3 つのパラメータだけをこの順で受け取る
-
- Delphi の場合:
procedure MethodName(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
-
- C++ の場合:
void MethodName(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse);
リソース クラスのメソッドが上記の要件をすべて満たさない場合、EMS サーバーはそのメソッドには API エンドポイントをマッピングしません。
エンドポイント メソッドの実装
エンドポイント メソッドの実装では、受け取った TEndpointResponse のインスタンスにデータを設定しなければなりません。これは通常、JSON データです。TEndpointResponse
の Body プロパティの SetValue メソッドを使って応答に JSON データを設定するか、SetBytes または SetStream を使ってデータをそのまま応答本体に書き込むことができます。
「チュートリアル:初めての EMS リソースを実装する」に簡単な例がありますので参照してください。
要求メソッド
エンドポイント メソッドの名前は、そのエンドポイント メソッドが処理する要求メソッドの名前で始まります。つまり、1 つのエンドポイント メソッドで複数の異なる要求メソッドを処理することはできません。
EMS サーバー API では以下の種類の要求メソッドをサポートしています。
名前 | 説明 |
---|---|
GET |
データを取得します。 |
PUT |
新しい項目を作成してその ID を取得します。 |
POST |
既存の項目を新しいデータで置き換えます。 |
PATCH |
既存の項目のデータの一部を更新します。 |
DELETE |
項目を削除します。 |
リソース サフィックス
リソース サフィックスとは、エンドポイント URL の末尾、リソース名の直後にくる文字列で、小文字で記述します。たとえば、エンドポイントにアクセスする URL が http://example.com/ems/myresource/item/count で、リソース名が "MyResource" であれば、そのエンドポイントのリソース サフィックスは "item/count"(または "/item/count")です。
各エンドポイント メソッドは、特定のリソース サフィックスにマッピングされます。EMS クライアント アプリケーションからリソースにアクセスするには、TBackendEndpoint コンポーネントの ResourceSuffix プロパティにリソース サフィックス文字列を設定する必要があります。
デフォルトでは、エンドポイント メソッドのリソース サフィックスは空文字列です。異なるリソース サフィックスをエンドポイント メソッドに割り当てるには、後でエンドポイント メソッドのマッピングをカスタマイズする必要があります。
リソース サフィックスは、必ず、リソース自体の URL からの相対パスで指定します。スラッシュ(/)で始まるリソース サフィックスをエンドポイント メソッドに割り当てると、最初のスラッシュは EMS サーバーによって無視されます。たとえば、"/item/count" と "item/count" はどちらも、http://example.com/ems/myresource/item/count などの同じエンドポイント URL を指す有効なリソース サフィックスです。
リソース サフィックスに使用できる特別なセグメント
セグメントとは、スラッシュ以外の文字を含む文字列です。リソース サフィックスは、スラッシュで区切られた複数のセグメントで構成することができます。たとえば、"item/count" には、"item" および "count" という 2 つのセグメントが含まれています。
リソース サフィックスでは、以下の特別なセグメントをサポートしています。
セグメント | 説明 |
---|---|
|
任意のセグメントと一致します。 たとえば、"*/count" というリソース サフィックスは、"foo/count" や "bar/count" と一致します。 |
|
この <識別子> は、"item" や "key" など任意の識別子でかまいません。 任意のセグメントに一致します。一致したセグメントは、識別子をキー、要求 URL 内の実際の文字列を値として TEndpointRequest.Params プロパティに格納されます。 たとえば、"{item}/bar" というリソース サフィックスは "foo/bar" と一致し、TEndpointRequest.Params プロパティに |
- メモ: これらの特別なセグメントは、それ自体が 1 つのセグメントとして完結した形でしか使用できません。"foo*/bar" や "{foo}bar/count" などのリソース サフィックスは、EMS サーバーによって、特別なセグメントではなく、"foo*" や "{foo}bar" のような通常の文字列として解釈されます。
エンドポイント名
エンドポイントの名前は、EMS コンソール UI 上でそのエンドポイントを表す表示用の文字列です。
デフォルトでは、エンドポイント メソッドが表すエンドポイントの名前は、そのメソッドの名前になります。エンドポイントに異なる名前を付けたい場合は、後でカスタマイズすることができます。
エンドポイント名はリソース内で一意でなければなりません。2 つの異なるエンドポイント メソッドに同じエンドポイント名を付けると、EMS サーバーは後で見つかったエンドポイント名の末尾に数値を追加して一意の名前にします。たとえば、エンドポイント メソッドが 2 つあるときに、マッピングを変更した結果、両方のエンドポイント名が "MyEndpoint" になると、最初のエンドポイント メソッドは元のエンドポイント名のままですが、2 番目のエンドポイント メソッドの名前は "MyEndpoint2" になります。
リソースのマッピングのカスタマイズ
リソース クラスを EMS サーバーに登録する前に、リソース クラスおよびエンドポイント メソッドを EMS サーバー API にどうマッピングするかを変更することができます。
リソース名、リソース サフィックス、エンドポイント名を変更できます。ただし、要求メソッドは変更できません。これは常に、エンドポイント メソッド名のプレフィックスで定義されます。
リソースのマッピングをカスタマイズするには、そのリソースのリソース属性オブジェクトを定義し、リソースの登録時にそのオブジェクトを使用します。Delphi の場合は、属性を使ってリソースのマッピングをカスタマイズすることもできます。
リソース属性オブジェクトの定義
リソース属性オブジェクトは TEMSResourceAttributes のインスタンスです。
リソース属性オブジェクトを使ってリソースのマッピングをカスタマイズする手順は以下のとおりです。
TEMSResourceAttributes
のインスタンスを作成します。- リソース属性オブジェクトのプロパティに、リソースで使用したいマッピングを設定します。
- そのオブジェクトを、リソースの登録時に RegisterResource の第 2 パラメータに指定します。
リソースのマッピングをカスタマイズするには、TEMSResourceAttributes
の以下のプロパティを使用できます。
プロパティ | 説明 |
---|---|
リソースの名前を指定します。 | |
特定のエンドポイント メソッド名に対して、そのエンドポイント メソッドのリソース サフィックスを指定します。 | |
特定のエンドポイント メソッド名に対して、そのエンドポイント メソッドが表すエンドポイントの名前を指定します。 |
- メモ: 定義するのは、変更したいマッピング データだけでかまいません。たとえば、ResourceName の値を変更しなければ、EMS サーバーはリソースのデフォルト名(リソース クラスの名前を基に作成されたもの)を使用します。
以下に例を示します。
- Delphi の場合:
// var MyResourceAttributes: TEMSResourceAttributes;
MyResourceAttributes.Create();
MyResourceAttributes.ResourceName := 'Resource';
MyResourceAttributes.ResourceSuffix['Get'] := '{item}';
MyResourceAttributes.EndPointName['Get'] := 'GetItem';
- C++ の場合:
std::auto_ptr<TEMSResourceAttributes> MyResourceAttributes(new TEMSResourceAttributes());
MyResourceAttributes->ResourceName = "Resource";
MyResourceAttributes->ResourceSuffix["Get"] = "{item}";
MyResourceAttributes->EndPointName["Get"] = "GetItem";
属性を使用したリソースのマッピングのカスタマイズ(Delphi)
Delphi で、リソース クラスとエンドポイント メソッドのマッピング データをカスタマイズするには、以下の属性を使って注釈を付けます。
メンバの種類 | 属性 | 説明 |
---|---|---|
リソース クラス |
リソースの名前を指定します。 | |
エンドポイント メソッド |
エンドポイント メソッドのリソース サフィックスを指定します。 | |
エンドポイント メソッドが表しているエンドポイントの名前を指定します。 |
以下に例を示します。
[ResourceName('Resource')]
TMyResource = class
published
[ResourceSuffix('{item}')]
[EndpointName('GetItem')]
procedure Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
end;
リソースの登録
リソース クラスとエンドポイント メソッドを定義したら、次に以下を行う必要があります。
- リソース クラスを TypeInfo に渡して、リソース クラスの RTTI 情報を取得します。
- リソース クラスの RTTI 情報を渡して RegisterResource を実行します。
RegisterResource
はパッケージの Register メソッドで呼び出します。
以下に例を示します。
- Delphi の場合:
RegisterResource(TypeInfo(TMyResource));
- C++ の場合:
RegisterResource(__typeinfo(TMyResource));
リソース属性オブジェクトを使ったリソースの登録
リソース クラスおよびエンドポイント メソッドのマッピング データをカスタマイズするためにリソース属性オブジェクトを作成した場合は、そのリソース属性オブジェクトを RegisterResource
の第 2 パラメータに渡します。
以下に例を示します。
- Delphi の場合:
RegisterResource(TypeInfo(TMyResource), MyResourceAttributes);
- C++ の場合:
RegisterResource(__typeinfo(TMyResource), MyResourceAttributes.release());