[Autonomous Database]OCI API Gateway経由でOracle管理ORDSを使ったREST APIにアクセスしてログを取得する

# はじめに
Autonomous DatabaseにはOracle管理のORDSが付属しておりすぐにREST APIの開発ができます。しかしOracle管理のORDSではREST APIへのアクセスログを残す方法がありません。そこで、API Gatewayとの組み合わせを試しました。

## 前提条件
+ DEMOUSER1というユーザーのEMP表を利用
+ Autonomous Databaseはプライベート・エンドポイントを利用。ただし、インターネット経由で付属ツールのアクセスができるようパブリック・アクセスを許可済み
+ Autonomous DatabaseとAPI Gatewayは同じプライべート・サブネットに配置
+ プライベート・サブネットにアクセスできるコンピュート・インスタンスを同じVCNのパブリック・サブネットに作成済み

# 1.REST APIを作成する
Autonomous Database（というかOracle Database）は二通りの方法でREST APIを作成できます。

+ AutoRESTによるデータベース・オブジェクトのRESTfulサービス化
+ 手動によるRESTfulサービスの作成

データベース・オブジェクトでAutoRESTを有効化するとそのオブジェクトにRESTでのアクセスができるようになります。とても簡単にデータベース・オブジェクトをRESTデータソースとして公開ができるのですが、事前定義された形式になるため、目的にあわない場合はハンドラをSQL、PL/SQLで設定する手動による作成が選べます。
今回は検証ということでAutoRESTでREST APIを作成します。Autonomous Databaseの場合はGUIのDatabase Actionsでできるのでさらに簡単です。

DEMOUSER1で**Database Actions**にログインし**SQL**にアクセスします。次に**EMP**表を検索し、**右クリックしてREST→有効化**を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/1d893f1b-cb39-4720-b51e-8dc7da58bd28.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/d18b8170-5f48-4b67-a12e-32f136ae76aa.png)

**オブジェクトのRESTの有効化**の画面が表示されます。今回はデフォルトのまま有効化します。コードの表示で実行されるSQLを確認することも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/d0ea711f-db29-4169-89e4-38278429c6c7.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/c3cfbbb2-b065-4a5c-a565-00f04e7242bb.png)

有効化後は**無効化**のほか**cURLコマンドの確認**ができるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/b4aade03-392b-4034-b774-0ca289e65cfd.png)

cURLコマンドは3つのターミナルでのコマンドが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/cf44b038-65a0-4f00-aa84-cbc3675b92c5.png)

コマンドはメソッド別にあり、例えばGET Singleだと値を指定してコマンドの確認ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/257ad521-fe25-4139-9283-1d6eabad192b.png)

試しにコマンドプロンプトで実行してみます。EMP表の内容はこちらです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/17acc75c-713f-4204-8b8a-6a9eb3093780.png)

7788を指定したコマンドをコピーアンドペーストしたところ、正しく7788の新井さんの結果が表示がされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/a453cfff-0e52-47eb-9706-b7233f40e937.png)

なお、AutoRESTで作成したREST APIはDatabase Actionsの**REST**で確認もできます。認証設定などはこちらで行うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/eb794d91-32f8-41c0-a933-0cde8b9f1312.png)

# 2.OCI API Gatewayを構成する
次に公開されている[チュートリアル](https://oracle-japan.github.io/ocitutorials/cloud-native/apigateway-for-beginners/#2oci-api-gateway%E3%81%B8%E3%81%AEapi%E3%81%AE%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E5%85%AC%E9%96%8B
)を参考にAPI Gatewayを構成します。
**開発者サービス→API管理→ゲートウェイ**を選択し、**ゲートウェイの作成**をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/3ddbd9ef-da74-414d-bb6d-a0279ccdebfc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/67a1ec72-e88c-4a92-9306-54cdd5fae089.png)

今回使用している検証環境の割り当て制限でパブリックIPが利用できなかったため、**タイプ**はプライベートとし、**ネットワークのサブネット**はプライベート・サブネットを指定しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/9401e449-ab84-4fe8-b962-7fd4878ee4cb.png)

作成が成功しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/7b73a339-7c38-4e81-9bd5-adca70c11bb8.png)

次にデプロイメントを作成します。**デプロイメント**を選択して、**デプロイメントの作成**をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/87186d3b-39b3-4f9f-8b52-b1426c5e2cf2.png)


**基本情報**は**名前**と**パス接頭辞**だけ指定して、後はデフォルトのままにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/d20994ae-d200-40c4-b883-4c2f9e8d8015.png)

**認証**は**認証なし**にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/0f0b2a98-9af6-4172-ac19-709141679150.png)

**ルート**は**単一バックエンドの追加**を選択し、1のcURLコマンドで試したAutoRESTで作成したREST APIのGET SingleのURLにアクセスさせるように設定していきます。
**バックエンド・タイプ**に**HTTP**、**メソッド**は**GET**を選択します。**パス**は```/accessemp/{id}``` としてみました。**URL**は**アクセスするREST APIのURL**になりますが、引数としてパスの```{id}```を渡したいので、コンテキスト変数を使って```${request.path[id]}```と指定します。API Gatewayのコンテキスト変数は[こちらのドキュメント](https://docs.oracle.com/ja-jp/iaas/Content/APIGateway/Tasks/apigatewaycontextvariables.htm)に記載があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/788ef084-683b-41b8-8f1c-c0f51fa9a5ce.png)

設定を確認し、**作成**をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/bd788671-2755-4720-ac4c-b4c6a4349559.png)

アクティブになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/66861c65-0ae6-4182-93e2-2476e5a14ca6.png)

ログも有効化します。左の**リソース**から**ログ**を選択し、**Access Logs**の**ログの有効化**を**On**にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/04efc33f-8917-4efa-9bf8-561278d1c405.png)

**ログの有効化**の画面が表示されます。今回はデフォルトのまま、**ログの有効化**をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/fc953c7b-41c8-42c0-a6e9-4c57152677ea.png)

**Access Logsのステータス**が**アクティブ**になりました。**ログ名**をクリックしてログを確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/2f03836d-b3c2-41cc-9e81-88979a2ece58.png)


# 3.アクセスしてみる
アクセスするURLは、```デプロイメントのエンドポイント＋ルーティングで設定したパス```になります。**デプロイメントのエンドポイント**は**ゲートウェイの詳細**、または**デプロイメントの詳細**からコピーができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/aa144a1d-f628-40b2-b555-876da31b3fc7.png)

API Gatewayのタイプをプライベートにしたので、パブリック・サブネットに配置したコンピュート・インスタンスからアクセスします。

```
[opc@dev1 ~]$ curl --location "https://********************.apigateway.ap-tokyo-1.oci.customer-oci.com/v1/accessemp/7788"

{"empno":7788,"ename":"新井 敦子","job":"アナリスト","mgr":7566,"hiredate":"1982-12-09T00:00:00Z","sal":3000,"comm":null,"deptno":20,"links":[{"rel":"self","href":"https://sya6vphk3pzlkhq-araadw1.adb.ap-tokyo-1.oraclecloudapps.com/ords/demouser1/emp/7788"},{"rel":"edit","href":"https://sya6vphk3pzlkhq-araadw1.adb.ap-tokyo-1.oraclecloudapps.com/ords/demouser1/emp/7788"},{"rel":"describedby","href":"https://sya6vphk3pzlkhq-araadw1.adb.ap-tokyo-1.oraclecloudapps.com/ords/demouser1/metadata-catalog/emp/item"},{"rel":"collection","href":"https://sya6vphk3pzlkhq-araadw1.adb.ap-tokyo-1.oraclecloudapps.com/ords/demouser1/emp/"}]}
```

正しく応答が返りました！
ログを確認してみると出力がされていることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/cbe1ea73-8730-48c6-b8a9-bfce4fda5e13.png)

詳細を参照すると以下のような情報が取得されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134317/0850a909-7139-4341-a01d-2a730aa930b0.png)

:::note warn
API Gatewayで扱えるデータサイズは最大20MBとなります。例えばデータ・ダウンロードの場合、データが20MBを超えているとエラーになりますので、データを直接返すのではなくObject Storageに出力するなどを検討してください。
:::

# おわりに
Oracle管理のORDSを使用したREST APIにOCI API Gateway経由でアクセスしてみました。　
API Gatewayを挟むと、REST APIのアクセス・ログからAPIの使用状況を把握することができるので、どのAPIが最も使用されているか、どのAPIが重要でないかなどといった分析が可能になります。また、ORDSのAPIをそのまま公開したくないという場合にもAPI Gatewayが利用できます。


# 参考情報
+ [OracleによるデータベースAPIの世界のナビゲート](https://blogs.oracle.com/oracle4engineer/post/ja-navigate-the-world-of-database-apis-with-oracle) 
+ [OCI API Gatewayハンズオン](https://oracle-japan.github.io/ocitutorials/cloud-native/apigateway-for-beginners/)