2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[ORDS] REST APIでADBからデータを取得する

2
Last updated at Posted at 2026-05-01

はじめに

この記事では認証認可に関する情報は記載しておりません。
Okta の Auth0 との連携について後日記事を投稿する予定ですが、REST API を外部に公開する際はネットワーク制限やセキュリティを強固にするための設定などを考慮した上でご検討ください。

Oracle Autonomous AI Database には、データベース上のデータや PL/SQL 処理を HTTPS の REST API として公開するための Oracle REST Data Services (ORDS) がデフォルトで用意されています。

ORDS を使うと、アプリケーション側から Oracle Database に直接接続するのではなく、以下のような REST API 経由でデータを取得できます。

curl https://<adb-host>/ords/<schema>/v1/customers/

本記事では、Autonomous AI Database 上に保存されている構造化データを、REST API で取得出来るようにする手順を紹介します。

ORDS とは

ORDS (Oracle REST Data Services) は、Oracle Database の HTTP(S) Web ゲートウェイです。
Oracle Database に ORDS を導入することで、Oracle Database Actions やデータベース用の REST API が使えるようになります。
この記事では主に REST API を使う機能にフォーカスします。

image.png

ORDS は HTTP(S) の GETPOSTPUTDELETE などのリクエストを受け取り、事前に定義した Module、Template、Handler のルーティングをもとに適切な処理を実行します。
Handler では SQL や PL/SQL を実行でき、SQL の結果は JSON として返せるため、React や Vue、Angular のようなフロントエンドアプリケーションから扱いやすくなります。

たとえば、以下のような使い方ができます。

  • テーブルやビューの内容を REST API として公開する
  • SQL の検索結果を JSON として返す
  • PL/SQL パッケージを REST API から呼び出す

OCI や Azure、GCP、AWS などで提供されている Autonomous AI Database には、既定で ORDS が導入されています。
そのため、通常の Oracle Database に ORDS を自前でインストールする場合とは異なり、ORDS 本体のインストール作業は不要です。

参考:

今回作るもの

今回は、以下のような読み取り専用 API を作成します。
データは検証用のものを用意します。
テーブルを作成する DDL やテストデータを INSERT する SQL クエリは後述します。

Method Path 内容
GET /ords/<schema>/v1/customers/ 顧客属性の一覧を取得
GET /ords/<schema>/v1/purchase-history/ 購買履歴の一覧を取得
GET /ords/<schema>/v1/customer-voices/ 顧客フィードバックの一覧を取得

レスポンスは ORDS の collection feed 形式で返ります。
典型的には以下のような JSON になります。

{
  "items": [
    {
      "id": 1,
      "customerId": "C-123456",
      "membershipRank": "Gold",
      "hasApp": "Y",
      "favoriteSports": "Running",
      "areaName": "Tokyo"
    }
  ],
  "hasMore": false,
  "limit": 100,
  "offset": 0
}

ORDS の構成要素

ORDS の REST API を PL/SQL で定義する場合、主に以下の 3 つを作成します。

Module

Module は、REST API のまとまりです。

たとえば、今回の API では simple_data_api.v1 という module を作り、base path を /v1/ にしています。

ORDS.DEFINE_MODULE(
  p_module_name    => 'simple_data_api.v1',
  p_base_path      => '/v1/',
  p_items_per_page => 100,
  p_status         => 'PUBLISHED',
  p_comments       => 'Simple read-only data API'
);

この定義により、以下のような URL の土台ができます。

https://<adb-host>/ords/<schema>/v1/

Template

Template は、Module 配下の URL パスを定義するものです。

たとえば customers/ という template を定義すると、以下の URL に対応できます。

https://<adb-host>/ords/<schema>/v1/customers/

定義は以下のようになります。

ORDS.DEFINE_TEMPLATE(
  p_module_name => 'simple_data_api.v1',
  p_pattern     => 'customers/',
  p_comments    => 'Customer attribute list without names'
);

Handler

Handler は、HTTP メソッドと実行する SQL / PL/SQL を紐づけるものです。

たとえば、GET /customers/ に対して SELECT ... FROM demo_customer_master を実行したい場合は、以下のように書きます。

ORDS.DEFINE_HANDLER(
  p_module_name    => 'simple_data_api.v1',
  p_pattern        => 'customers/',
  p_method         => 'GET',
  p_source_type    => ORDS.source_type_collection_feed,
  p_items_per_page => 100,
  p_comments       => 'Get customer attributes',
  p_source         => q'~
    SELECT id AS "id",
           membership_rank AS "membershipRank",
           has_app AS "hasApp",
           favorite_sports AS "favoriteSports",
           area_name AS "areaName"
    FROM   demo_customer_master
    ORDER  BY id
  ~'
);

ここで重要なのは p_source_type です。

今回のように複数行の SELECT 結果を JSON 配列として返す場合は、ORDS.source_type_collection_feed を使います。
1 件だけ返す詳細 API であれば、ORDS.source_type_collection_item を使うことが多いです。
PL/SQL の処理を実行してレスポンスを自分で組み立てたい場合は、ORDS.source_type_plsql を使います。

実際に試す

サンプルテーブルの作成

ここからは、実際に ORDS で公開するためのサンプルテーブルを作成します。

今回使用するテーブルは以下の 3 つです。

テーブル名 内容
DEMO_CUSTOMER_MASTER 顧客属性
DEMO_PURCHASE_HISTORY 購買履歴
DEMO_CUSTOMER_VOICES 顧客フィードバック

既に手元に公開したいテーブルがある場合は、この DDL は不要です。
その場合は、後続の ORDS 定義 SQL の SELECT を実テーブルに合わせて変更してください。

CREATE TABLE demo_customer_master (
  id                NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  cust_id           VARCHAR2(30) NOT NULL UNIQUE,
  membership_rank   VARCHAR2(30),
  has_app           VARCHAR2(1) CHECK (has_app IN ('Y', 'N')),
  favorite_sports   VARCHAR2(100),
  area_name         VARCHAR2(100)
);

CREATE TABLE demo_purchase_history (
  id                NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  purchase_id       NUMBER NOT NULL UNIQUE,
  cust_id           VARCHAR2(30) NOT NULL,
  purchase_date     DATE NOT NULL,
  purchase_amount   NUMBER(12, 0) NOT NULL,
  item_count        NUMBER(6, 0) NOT NULL,
  store_name        VARCHAR2(100),
  area_name         VARCHAR2(100),
  CONSTRAINT demo_purchase_history_customer_fk
    FOREIGN KEY (cust_id) REFERENCES demo_customer_master (cust_id)
);

CREATE TABLE demo_customer_voices (
  id                NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  voice_id          VARCHAR2(30) NOT NULL UNIQUE,
  cust_id           VARCHAR2(30) NOT NULL,
  post_date         DATE NOT NULL,
  category          VARCHAR2(50),
  sentiment_score   NUMBER(1, 0) CHECK (sentiment_score BETWEEN 1 AND 5),
  feedback_text     VARCHAR2(1000),
  CONSTRAINT demo_customer_voices_customer_fk
    FOREIGN KEY (cust_id) REFERENCES demo_customer_master (cust_id)
);

テストデータの投入

次に、動作確認用のデータを INSERT します。

この記事では REST API の作り方にフォーカスしたいため、データは少なめにしています。

INSERT INTO demo_customer_master (
  cust_id,
  membership_rank,
  has_app,
  favorite_sports,
  area_name
) VALUES (
  'CUST-001',
  'Gold',
  'Y',
  'Running',
  'Tokyo'
);

INSERT INTO demo_customer_master (
  cust_id,
  membership_rank,
  has_app,
  favorite_sports,
  area_name
) VALUES (
  'CUST-002',
  'Regular',
  'N',
  'Baseball',
  'Osaka'
);

INSERT INTO demo_customer_master (
  cust_id,
  membership_rank,
  has_app,
  favorite_sports,
  area_name
) VALUES (
  'CUST-003',
  'Platinum',
  'Y',
  'Football',
  'Kanagawa'
);

INSERT INTO demo_purchase_history (
  purchase_id,
  cust_id,
  purchase_date,
  purchase_amount,
  item_count,
  store_name,
  area_name
) VALUES (
  10001,
  'CUST-001',
  DATE '2026-04-01',
  12800,
  2,
  'Online Store',
  'Tokyo'
);

INSERT INTO demo_purchase_history (
  purchase_id,
  cust_id,
  purchase_date,
  purchase_amount,
  item_count,
  store_name,
  area_name
) VALUES (
  10002,
  'CUST-002',
  DATE '2026-04-03',
  7600,
  1,
  'Retail Store',
  'Osaka'
);

INSERT INTO demo_purchase_history (
  purchase_id,
  cust_id,
  purchase_date,
  purchase_amount,
  item_count,
  store_name,
  area_name
) VALUES (
  10003,
  'CUST-003',
  DATE '2026-04-06',
  21400,
  3,
  'Online Store',
  'Kanagawa'
);

INSERT INTO demo_customer_voices (
  voice_id,
  cust_id,
  post_date,
  category,
  sentiment_score,
  feedback_text
) VALUES (
  'VOICE-001',
  'CUST-001',
  DATE '2026-04-02',
  'Shoes',
  5,
  'The product was comfortable and easy to use.'
);

INSERT INTO demo_customer_voices (
  voice_id,
  cust_id,
  post_date,
  category,
  sentiment_score,
  feedback_text
) VALUES (
  'VOICE-002',
  'CUST-002',
  DATE '2026-04-05',
  'Wear',
  4,
  'The size and fabric were good.'
);

INSERT INTO demo_customer_voices (
  voice_id,
  cust_id,
  post_date,
  category,
  sentiment_score,
  feedback_text
) VALUES (
  'VOICE-003',
  'CUST-003',
  DATE '2026-04-08',
  'Gear',
  3,
  'It was useful, but I would like more options.'
);

COMMIT;

このあと作成する ORDS API では、store_namefeedback_text はレスポンスに含めません。
REST API ではテーブルの全列を公開する必要はなく、用途に応じて返す列を絞ることができます。

ORDS の定義を作成する

以下が、今回作成した ORDS 定義 SQL です。
こちらを対象のスキーマにて実行することで、外部に公開する REST API が作成可能です。

この SQL は、REST API の定義だけを作成します。
テーブル作成とテストデータ投入は、前のセクションで実行済みである前提です。

SET DEFINE ON

DEFINE CORS_ALLOWED_ORIGINS = 'http://localhost:5173,http://127.0.0.1:5173'

-- 新規スキーマで ORDS が未有効の場合だけ使用してください。
-- 既に ORDS が有効なスキーマで実行すると ORA-20049 になる場合があります。
--
-- BEGIN
--   ORDS.ENABLE_SCHEMA(
--     p_enabled             => TRUE,
--     p_schema              => USER,
--     p_url_mapping_type    => 'BASE_PATH',
--     p_url_mapping_pattern => LOWER(USER),
--     p_auto_rest_auth      => FALSE
--   );
-- END;
-- /

BEGIN
  ORDS.DEFINE_MODULE(
    p_module_name    => 'simple_data_api.v1',
    p_base_path      => '/v1/',
    p_items_per_page => 100,
    p_status         => 'PUBLISHED',
    p_comments       => 'Simple read-only data API'
  );

  -- ORDS 23c 以降では、モジュール単位の CORS 許可 Origin を設定できます。
  -- 利用中の ORDS バージョンにこの API がない場合は、
  -- ORDS 管理設定またはリバースプロキシで同等の CORS 設定を行ってください。
  ORDS.SET_MODULE_ORIGINS_ALLOWED(
    p_module_name     => 'simple_data_api.v1',
    p_origins_allowed => '&&CORS_ALLOWED_ORIGINS'
  );

  ORDS.DEFINE_TEMPLATE(
    p_module_name => 'simple_data_api.v1',
    p_pattern     => 'customers/',
    p_comments    => 'Customer attribute list without names'
  );

  ORDS.DEFINE_TEMPLATE(
    p_module_name => 'simple_data_api.v1',
    p_pattern     => 'purchase-history/',
    p_comments    => 'Purchase history list without store names'
  );

  ORDS.DEFINE_TEMPLATE(
    p_module_name => 'simple_data_api.v1',
    p_pattern     => 'customer-voices/',
    p_comments    => 'Customer feedback list without free text'
  );
END;
/

BEGIN
  ORDS.DEFINE_HANDLER(
    p_module_name    => 'simple_data_api.v1',
    p_pattern        => 'customers/',
    p_method         => 'GET',
    p_source_type    => ORDS.source_type_collection_feed,
    p_items_per_page => 100,
    p_comments       => 'Get customer attributes',
    p_source         => q'~
      SELECT id AS "id",
             'C-' || LPAD(TO_CHAR(ORA_HASH(cust_id, 999999)), 6, '0') AS "customerId",
             membership_rank AS "membershipRank",
             has_app AS "hasApp",
             favorite_sports AS "favoriteSports",
             area_name AS "areaName"
      FROM   demo_customer_master
      ORDER  BY id
    ~'
  );

  ORDS.DEFINE_HANDLER(
    p_module_name    => 'simple_data_api.v1',
    p_pattern        => 'purchase-history/',
    p_method         => 'GET',
    p_source_type    => ORDS.source_type_collection_feed,
    p_items_per_page => 100,
    p_comments       => 'Get purchase history',
    p_source         => q'~
      SELECT id AS "id",
             purchase_id AS "purchaseId",
             'C-' || LPAD(TO_CHAR(ORA_HASH(cust_id, 999999)), 6, '0') AS "customerId",
             TO_CHAR(purchase_date, 'YYYY-MM-DD') AS "purchaseDate",
             purchase_amount AS "purchaseAmount",
             item_count AS "itemCount",
             area_name AS "areaName"
      FROM   demo_purchase_history
      ORDER  BY purchase_date DESC, id DESC
    ~'
  );

  ORDS.DEFINE_HANDLER(
    p_module_name    => 'simple_data_api.v1',
    p_pattern        => 'customer-voices/',
    p_method         => 'GET',
    p_source_type    => ORDS.source_type_collection_feed,
    p_items_per_page => 100,
    p_comments       => 'Get customer feedback attributes',
    p_source         => q'~
      SELECT id AS "id",
             voice_id AS "voiceId",
             'C-' || LPAD(TO_CHAR(ORA_HASH(cust_id, 999999)), 6, '0') AS "customerId",
             TO_CHAR(post_date, 'YYYY-MM-DD') AS "postDate",
             category AS "category",
             sentiment_score AS "sentimentScore"
      FROM   demo_customer_voices
      ORDER  BY post_date DESC, id DESC
    ~'
  );
END;
/

COMMIT;

SQL のポイント

レスポンスに出す列を絞る

REST API では、テーブルの全列をそのまま公開する必要はありません。

今回の例では、画面表示に必要な項目だけを SELECT しています。

SELECT id AS "id",
       membership_rank AS "membershipRank",
       has_app AS "hasApp",
       favorite_sports AS "favoriteSports",
       area_name AS "areaName"
FROM   demo_customer_master

画面で扱いやすい JSON 名にする

SQL の alias を使って、JSON のフィールド名を画面側で扱いやすい名前にしています。

membership_rank AS "membershipRank"

curl で動作確認する

ORDS 定義が完了したら、curl で API を呼び出します。

API の URL は、Database Actions の "REST" ページから、対象の Module を選択することで確認可能です。
下図のように、Module に紐づいた各 Template の URL が確認可能です。

image.png

確認した URL を CURL コマンドで実行すると、下図のとおり期待どおり JSON が取得出来ました。

image.png

その他

作成した API ですが、Database Actions から Swagger っぽい UI で チェックすることが出来ます。
Database Actions の REST ページから作成した Module のページへ移動。
作成したモジュールから "OpenAPI View" をクリック。

image.png

すると見覚えのあるデザインの画面が表示されます。
もちろんここから実行も可能です。
image.png

また、"Export Module - OpenAPI" をクリックすることで、OpenAPI Specification の JSON データをダウンロードすることが可能です。

そのためここから OpenAPI の JSON をダウンロードし、それを利用して例えば OCI の API Gateway を簡単に作ることが出来たり、その他ベンダーの API 管理システムと便利に統合が可能です。
クライアントと ADB の間にゲートウェイを構築したい場合に便利ですね。

image.png

まとめ

ORDS を使うと、Oracle Database 上の SQL や PL/SQL を REST API として公開できます。

Autonomous Database では ORDS が事前構成済みのため、ORDS 本体のインストールは不要です。
必要な作業は、スキーマを REST Enabled にし、Module、Template、Handler を定義することです。

まずは SELECT 結果を返すだけの小さな API から試すと、ORDS の全体像をつかみやすいと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?