8 暗黙的パラメータ

この章では、明示的には宣言されない、RESTサービス・ハンドラで使用される暗黙的パラメータについて説明します。Oracle REST Data Services(ORDS)はこれらのパラメータをリソース・ハンドラに自動的に追加します。

8.1 暗黙的パラメータのリスト

次の表では、暗黙的パラメータを示します。

注意:

パラメータ名では大/小文字が区別されます。たとえば、:CURRENT_USERは有効な暗黙的パラメータではありません。

表8-1 暗黙的パラメータのリスト

名前 アクセス・モード HTTPヘッダー 説明 導入

:body

BLOB

IN

N/A

リクエストの本文を一時BLOBとして指定します。

2.0

:body_text

CLOB

IN

N/A

リクエストの本文を一時CLOBとして指定します。

18.3

:content_type

VARCHAR

IN

Content-Type

Content-Typeリクエスト・ヘッダーで示されるリクエスト本文のMIMEタイプを指定します。

2.0

:current_user

VARCHAR

IN

N/A

リクエストの認証済ユーザーを指定します。ユーザーが認証されていない場合、値はnullに設定されます。

2.0

:forward_location

VARCHAR

OUT

X-ORDS-FORWARD-LOCATION

このリクエストのレスポンスを作成するためにOracle REST Data ServicesがGETリクエストを転送する必要がある場所を指定します。

18.3

:fetch_offset

NUMBER

IN

N/A

ページに表示する最初の行のゼロ基点のオフセットを指定します。

18.3

:fetch_size

NUMBER

IN

N/A

ビューに取り込む最大行数を指定します。

18.3

:page_offset

NUMBER

IN

N/A

ページ区切りリクエストのゼロ基点のオフセットを指定します。

注意: :page_offsetパラメータは非推奨です。かわりに、:row_offsetパラメータを使用してください。

2.0

:page_size

NUMBER

IN

N/A

ビューに取り込む最大行数を指定します。

:page_sizeパラメータは非推奨です。かわりに、:fetch_sizeパラメータを使用してください。

2.0

:row_offset

NUMBER

IN

N/A

ページ区切りリクエストで表示する最初の行の1基点の索引を指定します。

3.0

:row_count

NUMBER

IN

N/A

ページ区切りリクエストで表示する最後の行の1基点の索引を指定します。

3.0

:status_code

NUMBER

OUT

X-ORDS-STATUS-CODE

リクエストのHTTPステータス・コードを指定します。

18.3

8.1.1 :bodyパラメータについて

:body暗黙的パラメータは、リクエスト本文のコンテンツを一時BLOBとして受信するためにリソース・ハンドラ内で使用されます。

注意:

POSTリクエストまたはPUTリクエストのみがリクエスト本文を持つことができます。HTTP仕様では、GETリクエストまたはDELETEリクエストでのリクエスト本文の使用は許可されません。

例8-1 例

次の例は、データベース表にリクエスト本文を格納するPL/SQLブロックを示しています。
begin
 insert into tab (content) values (:body);
end;

注意:

:body暗黙的パラメータは、PL/SQLブロック内で一度だけ間接参照されるようにしてください。複数回間接参照された場合、2番目以降の間接参照は空になります。これは、リクエスト本文はクライアントから一度しか送信されないためです。

次の例は、:bodyパラメータが2回間接参照されているため、意図したとおりに機能しません

begin
 insert into tab1(content) values (:body); -- request body will be inserted
 insert into tab2(content) values (:body); -- an empty blob will be inserted
end;
この制限を回避するには、使用前に:bodyパラメータの値をローカルPL/SQL変数に割り当てます。これにより、ローカル変数を2回以上間接参照できます。
declare
 l_content blob := :body;
begin
 insert into tabl(content) values(l_content);
 insert into tab2(content) values(l_content);
end;

8.1.2 :body_textパラメータについて

:body_text暗黙的パラメータは、リクエスト本文のコンテンツを一時CLOBとして受信するためにリソース・ハンドラ内で使用されます。通常、リクエスト本文のコンテンツはテキスト(JSONまたはHTMLコンテンツなど)であるため、リクエスト本文をCLOBとして受け取ることで、リソース・ハンドラの作成者は:body BLOBパラメータをCLOBインスタンスに変換する必要がなくなります。:bodyパラメータと同様に、:body_textパラメータはPL/SQLブロック内で一度だけ間接参照されるようにしてください

:body_text値をローカルのPL/SQL変数に割り当てることをお薦めします。こうすることで、PL/SQL変数をPL/SQLブロック全体で使用できるようになります。

8.1.3 :content_typeパラメータについて

:content_type暗黙的パラメータは、リクエストで渡されたContent-Typeリクエスト・ヘッダーの値を提供します。リクエストにContent-Typeヘッダーが存在しない場合、null値が返されます。

8.1.4 :current_userパラメータについて

:current_user暗黙的パラメータは、リクエストで認証されたユーザーの身元を提供します。

注意:

ユーザー認証が行われないシナリオでは、値はnullに設定されます。たとえば、パブリック・リソースに対するリクエストの場合、値はnullに設定されます。

8.1.5 :status_codeパラメータについて

:status_code暗黙的パラメータにより、レスポンスにHTTPステータス・コード値が含まれることをリソース・ハンドラで示すことができます。値は、HTTP仕様ドキュメントで定義されている数値のいずれかである必要があります。

8.1.6 :forward_locationパラメータについて

:forward_location暗黙的パラメータは、PL/SQLベースのリソース・ハンドラがリクエストに対するレスポンスを生成できるようにするためのメカニズムを提供します。

新しいリソースを作成するPOSTリクエストについて考えてみます。通常、REST APIに対するPOSTリクエストのレスポンスには、新しく作成されたリソースの場所(Locationレスポンス・ヘッダー内)と新しいリソースの表現が含まれています。レスポンスにLocationヘッダーが存在することは、指定した場所に対するレスポンスを生成できるGETリソース・ハンドラがあることを示しています。

POSTリソース・ハンドラにロジックを適用するかわりに、既存のGETリソース・ハンドラにタスクを委任して新しいリソースの表現をレスポンスに表示することができます。

次のリソース・ハンドラはPOSTハンドラを定義することで、レスポンスの生成をGETリソース・ハンドラに委任しています。

ords.define_handler(
  p_module_name => 'tickets.collection',
  p_pattern => '.',                     
  p_method  => 'POST',
  p_mimes_allowed => 'application/json',
  p_source_type => ords.source_type_plsql,
  p_source => '
   declare
    l_owner varchar2(255);
    l_payload clob;
    l_id number;
   begin
    l_payload := :body_text;
    l_owner := :current_user;
    l_id := ticket_api.create_ticket(
      p_json_entity => l_payload,
      p_author => l_owner
    );
    :forward_location := ''./'' || l_id;
    :status_code := 201;
   end;
  '
);
説明:
  • ords.define_handler APIを使用して、tickets.collectionという名前の既存のリソース・モジュールにPOSTハンドラを追加しています。

  • 値が'.'のp_patternは、POSTハンドラをリソース・モジュールのルート・リソースにバインドする必要があることを示しています。tickets.collectionのベース・パスが/tickets/の場合、POSTハンドラは/tickets/ URLパスにバインドされます。

  • p_mimes_allowedの値は、POSTリクエストのContent-Typeヘッダー値がapplication/jsonでなければならないことを示しています。

  • p_source_type値は、POSTハンドラのソースがPL/SQLブロックであることを示しています。

  • p_source値には、PL/SQLブロックのソースが含まれます。

    説明:

    注意:

    :body_text暗黙的パラメータがローカル変数に割り当てられているため、複数回の間接参照が可能です。
    • POSTリクエストを発行したユーザーの身元は、:current_user暗黙的パラメータによって判別されます。

    • このPL/SQLブロックはリクエスト・ペイロードを格納するタスクをPL/SQLパッケージ・レベル・ファンクションに委任しています。PL/SQLブロックにはHTTPリクエストとPL/SQLパッケージの起動をつなぐロジックのみを含める必要があります。

      注意:

      すべてのデータ変更操作がPL/SQL APIでラップされている場合、PL/SQLブロックは個別にテストできます。長時間および複雑なPL/SQLブロックはコードがアンチパターンであることを示しており、テストとメンテナンスが困難です。
    • PL/SQLパッケージ・レベル・ファンクションは新しく作成されたリソースのIDを返します。

    • :forward_location暗黙的パラメータには、'./' || l_idの値が割り当てられます。たとえば、l_idの値が4256の場合、:forward_locationの値は/tickets/4256になります。

      ORDSは先行するPL/SQLブロックを評価し、:forward_location暗黙的パラメータに割り当てられた値をチェックするときに、指定された場所(例: /tickets/4256)に対してGETリクエストを開始し、GETリクエストから生成されたレスポンスをPOSTリクエストのレスポンスとして返します。また、ORDSは場所レスポンス・ヘッダーをレスポンスに含め、ここに:forward_location値の完全に解決されたURLを格納します。

    • :status_code暗黙的パラメータには、HTTPレスポンス・ステータス・コード値が割り当てられます。201(作成済)ステータス・コードは、新しいリソースが作成されたことを示します。この値は、GETリクエストで生成されたステータス・コードを上書きします。

8.1.7 ページ区切り暗黙的パラメータについて

次の表に、ページ区切り暗黙的パラメータを示します。

注意:

Oracle REST Data Servicesは、問合せパラメータ、pageoffsetおよびlimitの使用を予約します。前述の問合せパラメータ名のいずれかを使用して、名前付きバインド・パラメータを使用するRESTサービスを定義することはできません。かわりに、RESTサービスでは次の表に示す適切なページ区切り暗黙的パラメータを使用する必要があります。

表8-2 ページ区切り暗黙的パラメータ

名前 説明 ステータス

:page_offset

ページ区切りリクエストのゼロ基点のページ・オフセットを指定します。

非推奨

:page_size

Recovery Appliance

非推奨

:row_offset

ページ区切りリクエストで表示する最初の行の索引を指定します。

お薦めしません

:row_count

ページ区切りリクエストで表示する最後の行の索引を指定します。

お薦めしません

:fetch_offset

ページに表示する最初の行のゼロ基点の索引を指定します。

お薦めします

:fetch_size

ビューに取り込む最大行数を指定します。

お薦めします

8.1.7.1 :page_offsetパラメータについて

:page_offset暗黙的パラメータは下位互換性のために提供されるため、source_type_queryソース・タイプのリソース・ハンドラでのみ使用されます。

注意:

  • source_type_queryソース・タイプは非推奨です。かわりにsource_type_collectionフィード・パラメータを使用してください。

  • :page_offset暗黙的パラメータは非推奨です。かわりに:row_offset暗黙的パラメータを使用してください。

8.1.7.2 :page_sizeパラメータについて

:page_size暗黙的パラメータは、ページに取り込む最大行数を指定するために使用されます。:page_sizeパラメータは下位互換性のために提供されます。このパラメータは非推奨です。かわりに:fetch_size暗黙的パラメータを使用してください。

8.1.7.3 :row_offsetパラメータについて

:row_offset暗黙的パラメータは、ページに表示する最初の行の数を示します。:row_offset暗黙的パラメータが使用されるのは、ラッパー・ページ区切り問合せとrow_number()(Oracle11g以前のリリースで使用される)の両方を使用している場合です。Oracle12c以降のリリースでは、:row_offsetパラメータのかわりに、:fetch_offset暗黙的パラメータと行制限句を使用することをお薦めします。

8.1.7.4 :row_countパラメータについて

:row_count暗黙的パラメータを使用して、ページに表示する行数を指定します。:row_count値は、:row_offsetとページ区切りサイズの合計の値です。:row_count暗黙的パラメータは、ラッパー・ページ区切り問合せ(Oracle Database11g以前のリリースで使用されていた)とrow_number()メソッドを使用してページ区切りを実装する場合に便利です。Oracle Databaseリリース12c以降では、かわりに:fetch_sizeパラメータと行制限句を使用することをお薦めします。

8.1.7.5 :fetch_offsetパラメータについて

:fetch_offset暗黙的パラメータは、指定されたページに表示する最初の行のゼロ基点のオフセットを示すために使用されます。:fetch_offset暗黙的パラメータは、Oracle12c以降のリリースで使用が推奨されている行制限句を使用してページ区切りを実装する場合に使用されます。

8.1.7.6 :fetch_sizeパラメータについて

:fetch_size暗黙的パラメータは、ページに取り込む最大行数を指定するために使用されます。ORDSでは:fetch_sizeの値が常にページ区切りサイズ+1に設定されます。余分な行があるかどうかに基づいて、ORDSは結果に後続のページがあるかどうかを判断します。

注意:

問合せされた余分な行はページに表示されません。
8.1.7.7 自動ページ区切りについて

この項では、自動ページ区切りプロセスについて説明します。

ソース・タイプsource_type_collection_feedまたはsource_type_queryのGETリソース・ハンドラにゼロ以外のページ区切りサイズ(p_items_per_page)が設定されていて、さらにGETリソース・ハンドラのソースが、前の項で説明した暗黙的ページ区切りパラメータのいずれも間接参照していない場合は、ORDSは問合せをページ区切り句にラップし、リクエストされたページの値のみが含まれるよう問合せ結果を制限します。自動ページ区切りでは、リソース・ハンドラの作成者はページ区切りサイズを指定するだけでよく、リソースのページ区切りに必要な残りの作業はORDSによって自動的に処理されます。

注意:

すべてのリソース・モジュールにはデフォルトのページ区切りサイズ(p_items_per_page) 25が設定されています。そのため、デフォルトで自動ページ区切りが有効になります。
8.1.7.8 手動ページ区切りについて

この項では、手動のページ区切りプロセスについて説明します。

シナリオによっては、ページ区切りプロセスをORDSに委任するのではなく、GETリソース・ハンドラ自身でページ区切りを実行しなければならない場合があります。このような場合、GETリソース・ハンドラのソースは、前述の項で説明した1つまたは複数の暗黙的ページ区切りパラメータを間接参照します。

注意:

GETリソース・ハンドラ側で必要なページ区切りサイズを指定し、ORDSが暗黙的ページ区切りパラメータで必要な値を正しく計算できるようにする必要があります。

行制限句を使用した手動ページ区切りの例

次の例は、行制限句を使用して問合せ結果セットをページ区切りするRESTサービスを定義しています。この方法で手動のページ区切りを実装することをお薦めします。

begin
 ords.define_service(
   p_module_name => 'example.paging',
   p_base_path => '/example/',
   p_pattern => '/paged',
   p_items_per_page => 7,
   p_source => 'select * from emp e order by empno desc offset :fetch_offset rows fetch next :fetch_size rows only'
 );
 commit;
end;

row_number()メソッドを使用した手動ページ区切りの例

次の例は、ラッパー問合せおよびrow_number()メソッドを使用するRESTサービスを定義しています。このアプローチはお薦めしません。

begin
ords.define_service(
   p_module_name => 'example.paging',
   p_base_path => '/example/',
   p_pattern => '/paged',
   p_items_per_page => 7,
   p_source => 'select * from (select q_.* , row_number() over (order by 1) rn__ from (select * from emp e order by empno desc) q_ )where rn__ between :row_offset and :row_count'
 );
 commit;
end;