LoginSignup
7
6

More than 3 years have passed since last update.

Oracle Autonomous DatabaseのREST Data ServicesでブログのREST APIを作ろ

Last updated at Posted at 2019-08-05

背景

Oracle REST Data ServicesがOracle Autonomous Database(ATP / ADW)で利用可能になりました。
ネイティブのOracle RESTデータサービス(ORDS)を使用し、Autonomous Database(自律型データベース)用のRESTサービスを開発およびデプロイできます。

そこで、ADB上のORDSにて、典型的なブログアプリケーション(REST API)を作ってみました。

環境準備・接続確認

■ ATPインスタンスの作成

Autonomous Database では、数回クリックするだけで簡単にインスタンスが作成できます。
(CPU、ストレージが不足した場合は、ダウンタイムなしでいつでもOCPUとストレージを拡張できます。)

image.png

ATPインスタンスが起動しました。

image.png

■ ATPインスタンスへの接続の作成(SQL Developer)

[DB Connection]ボタンをクリックして、認証情報(Wallet)ファイルをダウンロードしてください。

image.png

Walletファイルをダウンロードしたら、SQL Developerで新しい接続を作成します。

image.png

■ REST APIで操作対象とするスキーマ、および表を作成(users表、blogs表)

SQL Developerより以下を実行します。

-- Create Application User by ADMIN.
CREATE USER ORDSBLOG IDENTIFIED BY <PASSWORD>;

-- Grant privileges
GRANT CREATE SESSION TO ORDSBLOG;
GRANT DWROLE TO ORDSBLOG;
GRANT UNLIMITED TABLESPACE TO ORDSBLOG;

SQL Developerperにて、新ユーザ(ORDSBLOG)の接続を作成します。接続名を右クリックし、「Enable REST Services...」をクリックします。

image.png

「Enable schema」チェックボックスをオンにして、このスキーマのRESTサービスを有効にします。

image.png

もしくは以下をadminユーザにて実行すると、ORDSBLOGスキーマのRESTサービスも有効できます。(★)

BEGIN
   ORDS_ADMIN.ENABLE_SCHEMA(
     p_enabled => TRUE,
     p_schema => 'ORDSBLOG',
     p_url_mapping_type => 'BASE_PATH',
     p_url_mapping_pattern => 'ordsblog',
     p_auto_rest_auth => TRUE
   );
   COMMIT;
END;
/

以下はORDSBLOGユーザにて実施してください。

-- Create tables 
CREATE TABLE ORDSBLOG.USERS (
    ID      NUMBER GENERATED ALWAYS AS IDENTITY,
    NAME    VARCHAR2(200)  NOT NULL,
    CONSTRAINT USER_ID_PK PRIMARY KEY (ID)
);

CREATE TABLE ORDSBLOG.BLOGS (
    ID          NUMBER GENERATED ALWAYS AS IDENTITY,
    AUTHOR_ID   NUMBER  NOT NULL CONSTRAINT USER_ID_FK
                REFERENCES ORDSBLOG.USERS(ID),
    TITLE       VARCHAR2(200),
    CONTENT     VARCHAR2(32767),
    CONSTRAINT BLOG_ID_PK PRIMARY KEY (ID)
);

■ 各テーブルに対するRESTサービスの有効化

以降の手順はSQL DeveloperでORDSBLOGユーザでログインしなおしてから実施してください。

image.png

[Authorization required]チェックボックスをオフにします。
(簡単にするためにここでは認証は不要として記載します。認証ありの場合は後述)

image.png

作成する内容を確認して[Finish]をクリックします。

image.png

これで、テーブルusers用のREST APIを使用する準備が整いました。

■ URIエンドポイントの取得、動作確認

APIにアクセスするためのURIエンドポイントの取得はいくつか方法がありますが、ここでは、作成したATPインスタンスのサービスコンソールから取得します。

OCIのコンソールを開いてATPインスタンスのページに移動し、Service Consoleをクリックします。

image.png

次に[Development]をクリックし、[SQL Developer Web]タイルを右クリックしてそのリンクをコピーします。

image.png
image.png

以下のようにリンクを得るべきです。admin / _sdw /?nav = worksheetの部分を、作成したスキーマ名とRESTサービスを有効にしたテーブル名に置き換えます。

旧:https://<DB_NAME>.adb.<REGION>.oraclecloudapps.com/ords/admin/_sdw/?nav=worksheet
新:https://<DB_NAME>.adb.<REGION>.oraclecloudapps.com/ords/ordsblog/users/

下のスクリーンショットに示すように、このURIエンドポイントに直接アクセスすることでJSON形式の応答を取得できるはずです。
(RESTサービスを有効にしたときに承認チェックを有効にすれば、認証の設定が可能)

尚、ここでは便利なツールpostmanを使ってREST APIをテストしていますが、その他CURL等を利用して確認することも可能です。

テーブルusersにはレコードがないので、itemsは[]です。

image.png

テーブルのユーザーのメタデータを確認するために、 describebyリンクをクリックすることもできます。

image.png
image.png

ご覧のとおり、ADBインスタンスがある限り、RESTサービスを有効にするだけで、REST APIからテーブルにアクセスできるようになります。 とても簡単ですね。

ADBでORDSを使用するためのより良い方法

環境構築、接続作成にてまずは簡単にアクセスする方法を記載しましたが、実際には接続ナビゲータバーに表示されている「REST Data Services」の下の[Modules]と[Templates]を使用し、リソースへのアクセスを制御することをお勧めします。

image.png

■ RESTサービスの無効化方法

テーブルusersにおける[Enable object]チェックボックスをオフにします。
自分のデータを制御なしで公開することを望む人は誰もいないでしょう。

image.png

テーブルusersのRESTサービスが無効になると、同じリンクにアクセスしたときに 404 Not Foundエラーが発生します。 それが私たちが期待していたことです。

image.png

モジュール/テンプレート/ハンドラの使用

ユーザを取得するためにモジュール/テンプレート/ハンドラを使ってみます。

モジュールの作成

[REST Data Services]の下の[Modules]を右クリックし、[New Module]をクリックして新しいモジュールを作成します。

image.png

Module NameとURI Prefixを入力し、「Publish – Make this RESTful Service available for use」チェックボックスを選択します。

image.png

「Next」をクリックしてテンプレートを指定してください。 登録機能を提供するためにこのURIを使います。

image.png

要約を確認して、「Finish」をクリックします。

image.png

これで、usersというモジュールとnewというテンプレートが作成されました。

image.png

これは、以下のようにREST APIエンドポイントを作成しました。

https://<DB_NAME>.adb.<REGION>.oraclecloudapps.com/ords/ordsblog/users/new

このリンクにアクセスしようとしても、まだこのエンドポイントにハンドラを追加していないため、404 Not Foundエラーが発生します。

このエンドポイントを使用して登録機能を提供することを計画していましたが、テスト目的で、今のところこのエンドポイント用のGETハンドラーを追加します。

image.png

ハンドラワークシートにおいて、テーブルusersに単純なクエリ select * from usersを入力して保存します。

image.png

エンドポイントに再度アクセスしてください。

https://<DB_NAME>.adb.<REGION>.oraclecloudapps.com/ords/ordsblog/users/new

やった! APIが動作することが確認できました。

image.png

新しいユーザーの登録(POST)

このエンドポイントを使って新しいユーザーを登録するために、POSTハンドラを追加しましょう。

テンプレートnewを右クリックして、新しいPOSTハンドラを追加します。

image.png

[Apply]をクリックしてください。

image.png

POSTリクエストを処理するには少し複雑ですが、入力パラメータと出力レスポンスの内容に注意する必要があります。 以下のように新規ユーザーの作成を処理するプロシージャを使用します。

image.png

create or replace PROCEDURE ADD_USER (
    P_USER_NAME    IN  USERS.name%TYPE,
    P_OUT_ID      OUT USERS.id%TYPE,
    P_OUT_TOTAL   OUT INTEGER
)
AS
BEGIN
    INSERT INTO USERS (name)
    VALUES (P_USER_NAME)
    RETURN id INTO P_OUT_ID;

    SELECT COUNT(id) INTO P_OUT_TOTAL FROM USERS;

EXCEPTION
    WHEN OTHERS
    THEN HTP.print(SQLERRM);
END;

POSTハンドラで、今作成したプロシージャを呼び出し、リクエストから取得したパラメータを渡します。

image.png

BEGIN
    ADD_USER(P_USER_NAME   => :USER_NAME,
            P_OUT_ID       => :NEW_USER_ID,
            P_OUT_TOTAL    => :TOTAL);
commit;
END;

応答として、クライアントが次の動きを決定できるように新しく作成されたユーザーIDを返し、また全ユーザーの総数も返します。 以下のようにパラメータを設定します。

image.png

これで、POSTハンドラは準備完了です。 新しいユーザーを作成するためにJSON形式でユーザー情報をポストします。
JSONのキーはハンドラプロシージャの定義と同じである必要があります。

postmanクライアントで、リクエスト・メソッドはPOSTを選択し、エンドポイントURIを入力し、Body / RawセクションにJSON形式でユーザー情報を入力します。 (jsonファイルを使用してrawの代わりにbinaryを選択することもできます)

image.png

{
    "USER_NAME":"user01"
}

また、ヘッダの "Content-Type"を "application / json"に設定する必要があります。

image.png

[Send]ボタンをクリックすると、レスポンスのステータスが200 OK、新しいユーザーIDとレスポンス内のユーザーの総数が表示されます。

image.png

SQL Developerでは、新しく作成されたユーザーレコードを確認することもできました。

image.png

すべてのユーザーを取得するためのGETハンドラがあることを覚えていますか。 それを試してみましょう。

image.png

ユーザープロファイルを確認する(GET)

ユーザーが登録されると、ユーザーのプロフィールを表示するためにユーザー情報を提供する必要があることは明らかです。

これを行うためにshowエンドポイントを作成しましょう。

image.png

ユーザー情報を提供するためのGETハンドラを追加します。

image.png

image.png

ハンドラーでのクエリーは非常に簡単です。クエリーを完了するには、クエリー・パラメーターとしてユーザーIDを提供します。

image.png

以下のようにクエリを開始すると、期待通りにユーザー情報が得られます。

https://<DB_NAME>.adb.<REGION>.oraclecloudapps.com/ords/ordsblog/users/show?id=6

image.png

ブログを処理する

次に、REST APIを介して全てのCRUD動作をテーブルblogsに対して実施してみましょう。

最初のブログを投稿する(POST)

新しいユーザーハンドラと同様に、すでにこれに慣れていると思います。
データ挿入を処理するプロシージャを作成し、POSTハンドラでそのプロシージャを呼び出します。

image.png

予想される応答を確認するのに、問題が発生してはいけません。

image.png

自分のブログをすべて一覧表示する(GET)

それはまだGETリクエストです、唯一の違いはSQLクエリがブログを検索できるようにユーザーIDを渡すことです。

image.png

image.png

ブログを更新する(PUT)

以前に投稿したブログを更新したい場合はどうなりますか? そのためにはPUTメソッドを使用してください。

updateテンプレートを作成します。

image.png

POSTも動作しますが、更新作業を行うためのPUTハンドラを追加します。REST APIのベストプラクティスによれば、意図を示すためにPUTを使用する必要があります。

image.png

ブログの更新を処理するプロシージャは作成するのと似ています。

image.png

PUTハンドラーでブログ更新プロシージャを呼び出します。

image.png

postmanのクライアントでは、リクエストメソッドをPUTに設定し、Bodyセクションに新しいブログ情報を入力します。

image.png

更新されたブログを確認してください。

image.png

何? ショーブログエンドポイントを持っていませんか? そのようなGETハンドラを実装するのはあなたにとってとても簡単ですよ。

ブログを削除する(DELETE)

ブログ内の何かが古くなっていて、もうそれを残したくない場合は、いつでもブログを削除するためのDELETEハンドラを実装できます。

deleteテンプレートを追加します。

image.png

DELETEハンドラを作成します。

image.png

削除したいブログのIDを忘れずに渡してください。

image.png

postmanのクライアントでは、DELETEとしてリクエストメソッドを選択し、今実装したエンドポイントにリクエストを送信します。

image.png

今#2ブログだけを見ることができます。

image.png

リソースを保護する

Basic Auth

今までは、誰でも私たちのリソース(ユーザー、ブログ)に対して何でもすることができます。 明らかに、私たちはリソースを保護するようになりました、それはORDSのprivilegesを利用することによってそうすることができます。

image.png

[REST Data Services]の下の[Privileges]を右クリックして、新しいPrivilegesを作成します。 Name, Title, Descriptionを入力します。 簡単にするために、1つの特権ですべてのモジュールを保護します。
すべてのモジュール(users, blogs)を[Protected Modules]セクションに追加します。

image.png

新しく作成された権限Demoを見ることができます。

image.png

ユーザーの情報をもう一度要求しようとすると、下のように401 Unauthorizedエラーが発生します。

image.png

Webブラウザを使用してAPIをテストしている場合は、sign inをクリックしてDBユーザー資格情報を入力してパスすることができます。

postmanクライアントの「Authorization」タブで、Basic Authとして「TYPE」を選択し、DBユーザー資格情報を入力します。 リクエストを送信すると、ユーザー情報が表示されます。

image.png

OAuthクライアントアプリケーションを登録する

このREST APIを構築する目的は、フロントエンドまたはその他の承認されたサードパーティ製アプリケーションにデータアクセス機能を提供することです。BasicAuthは明らかにそうするための適切な方法ではありません。

OAuth 2.0は、REST APIを提供するHTTPサーバーがエンドユーザーに代わってサードパーティのアプリケーションへのアクセスを制限する手段を提供する標準のインターネットプロトコルです。

  • サードパーティ製アプリケーションの作成者は、クライアントの資格情報を取得するためにアプリケーションを登録する必要があります。
  • クライアント認証情報を使用して、サードパーティ製アプリケーションはエンドユーザーにアクセスを承認するように促すWebフローを開始します。

前述のように、OAuthを使用することで、クライアントアプリケーションは登録して承認を受けることでREST APIにアクセスできます。 そして幸いなことに、このフローはデフォルトでORDSに組み込まれています。

クライアントアプリケーションを登録するには、次のURLにアクセスする必要があります。

https://<DB_NAME>.adb.<REGION>.oraclecloudapps.com/ords/ordsblog/oauth/clients/

image.png

DBユーザー資格情報でサインインすると、まだクライアントが登録されていないことがわかります。

image.png

[New Client]をクリックして必要な情報を入力し、[Create New Client]をクリックします。

image.png

クライアントは登録されていますがまだ承認されていません。 この登録済みクライアントの詳細を表示するには、「Edit」アイコンをクリックします。

image.png

生成されたClient identifier、Unique Value、およびAuthorization URを確認できます。

image.png

Authorization URI をクリックして、DBユーザー資格情報でサインインします。 クライアント承認ページが表示されます。 このリクエストを承認するには、承認ボタンをクリックしてください。 拒否も可能です。

image.png

リクエストを承認すると、Webページはクライアントを登録したときに指定したURLにリダイレクトされます。 重要な点は、リダイレクトされたURLの次の項目です。

http://example.org/redirect#token_type=bearer&access_token=XErqh-jlHNSoXGe9JX5m7Q&expires_in=3600&state=f084f3c8-d567-e1c8-fb83-81aabacc9b54

  • Token_type: bearer
  • Access_token: XErqh-jlHNSoXGe9JX5m7Q
  • Expires_in: 3600
  • State:f084f3c8-d567-e1c8-fb83-81aabacc9b54

Token_typeとaccess_tokenは、クライアントアプリケーションがREST APIにアクセスしようとしたときの重要な情報です。 REST APIへのすべてのリクエストにそれらを含める必要があります。

image.png

保護されたREST APIにアクセスするために必要なものがすべて揃ったので、アクセストークンを使用してユーザーのプロファイルを取得してみましょう。

postmanクライアントで、「Authorization Type」を「Bearer Token」として選択し、access tokenを入力します。 それからリクエストを送りなさい、あなたはもう401 Unauthorizedエラーを見るべきではありません。

image.png

GETハンドラーだけでなく、正しいアクセストークンを提供する限り、ブログの更新など、すべてのハンドラーにアクセスできます。

image.png

image.png

逆に、クライアントアプリケーションが正しいアクセストークンを提供できない場合、それは私たちのリソースからブロックされます。

image.png

これで、私たちのブログアプリケーション用のセキュアでフル機能の(サンプル)REST APIができました。 そして、Autonomous DatabaseにおけるORDSの基本的な使い方にはもう慣れていると思います。 ORDSとOracle Autonomous Databaseについてもっと知りたい場合は、以下の参考文献を参照してください。

参考

共著者

7
6
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
7
6