※ 本記事は、Martin Bachによる”Using the JavaScript fetch API in Oracle Database 23c Free-Developer Release“を翻訳したものです。

2023年7月24日


MozillaのDeveloper Networkから引用するために… Fetch APIは JavaScriptインターフェースを提供し、リクエストや応答などのプロトコルの部分へのアクセスと操作を行います。また、ネットワーク全体でリソースを非同期にフェッチする簡単で論理的な方法を提供するグローバルfetch()メソッドも提供します。

GraalVMを搭載したOracleのMultilingual Engine (MLE)では、Linux x86-64でOracle Database 23c Free-Developer Release用のJavaScriptフェッチAPIを実装しています。fetch()コールが利用可能になったため、多くの興味深いユースケースを便利な方法で実装できます。リモートREST-APIを起動すると、最も一般的なユースケースになる可能性があります。この記事では、フェッチAPIを使用してRESTコールを起動し、HTTPSを使用してRESTエンドポイントから情報を取得する方法を学習します。この特定のRESTエンドポイントは、OracleのRESTfulデータ・サービス、ORDSのローカル・インスタンスによって提供されます。

ネットワーク・アクセス

Oracle Databaseでは、管理者がファイングレイン・アクセス制御エントリに基づいてネットワークI/Oを明示的に許可する必要があります。そのトピックの詳細は、データベース・セキュリティ・ガイドを参照してください。リモート・リソースに対してネットワーク・コールを行う前に、特権アカウントでこれらを有効にする必要があります。

データベース・ユーザーの作成

次のsnippetを使用して、(プラガブルな)データベースにローカル・ユーザーを作成できます。このユーザーは、リモート・ネットワークAPIの起動を許可されます。

create user demouser identified by &password
default tablespace users
temporary tablespace temp
quota 100M on users;

grant db_developer_role to demouser;
grant execute on javascript to demouser;

デモ・ユーザーにネットワークI/Oの実行を許可

次のステップでは、demouserがネットワークI/Oを実行できるようにする必要があります。概要に従って、アクセス制御エントリ(ACE)をアクセス制御リスト(ACL)に追加することで、これを行います。

BEGIN
    DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
        host => '&targetHost',
        ace  =>  xs$ace_type(
            privilege_list => xs$name_list('http'),
            principal_name => 'DEMOUSER',
            principal_type => xs_acl.ptype_db
        )
    );
END;
/

snippetでは、ORDSインスタンスのホスト名を入力するように求められます。プロトコルまたはポートを指定する必要はありません。ORDS.example.comのような完全修飾ホスト名(fqdn)を追加するだけです。

情報を取得

demouserとしてプラガブル・データベースに接続します。DB_DEVELOPER_ROLEのおかげで、アカウントにはデータベースにJavaScriptモジュールを作成する権限があります。

JavaScriptを使いましょう

次のJavaScriptモジュールを使用して、https経由でフェッチを実行できます。RESTエンドポイントは認証を必要としません。これは、例を単純に保つための意識的な決定でした。必要に応じて、OAuth2またはその他の認証メソッドをORDSに追加し、JavaScriptコードで制御できます。

create or replace mle module fetch_demo_module language javascript as

import "mle-js-fetch";

export async function fetchExample(url) {

    if (url === undefined || url.length < 0) {
        throw Error("please provide a URL in the form http://ords-server:port/ords/...");
    }

    const response = await fetch(
        url,
        {
            credentials: "include"
        }
    );

    if (! response.ok) {
        throw Error(`An error occurred: ${response.status}`);
    }

    const data = response.json();

    return data;
}
/

次のステップでは、モジュールを配置してコール指定を作成し、SQLおよびPL/SQLが使用されている任意の場所からJavaScriptコードを起動できるようにします。:

create or replace function fetch_example(
    p_url varchar2
) 
return json
as mle module fetch_demo_module
signature 'fetchExample(string)';
/

コントロールがプロンプトに戻るとすぐに、新しい機能を提供できます。

テスト

JavaScriptモジュールは、ORDSインスタンスからJSONデータを返すか、何か問題が発生した場合に例外をスローします。次のSELECT文を使用して、TLSで保護されたRESTエンドポイントを起動できます。:

select fetch_example('&restendpoint');

以前にUTL_HTTPを使用してTLSで保護されたリソースに接続したユーザーは、ORA-29024 Certification validation Failureというエラー・メッセージをすぐに理解できます。:

SQL> select fetch_example('&restendpoint');

Error starting at line : 1 in command -
select fetch_example('https://...')
Error report -
ORA-04161: TypeError: ORA-29024: Certificate validation failure
ORA-04171: at callUtlHttp (mle-js-fetch:2723:25)

以前は、Oracle Database 23c Free-Developer Releaseより前では、ウォレットを作成し、Webサービスの証明書を取得してウォレットに格納し、ウォレットをデータベース・ユーザーが使用できるようにする必要がありました。幸い、これは過去のものです! Oracle Database 23c Free-Developer Releaseは、オペレーティング・システムの証明書ストアを利用して、すべてのユーザーの生活をはるかに簡単にすることができます。最初のステップは、フェッチ・コールを再度呼び出す前に、システムの証明書ストアを使用するようにOracleに指示することです。:

begin
    utl_http.set_wallet('system:');
end;
/

select fetch_example('https://ords-server:8443/ords/schema/table/');

これで出来上がりです! APIコールの出力を表すJSONが多数表示されます。

まとめ

JavaScriptをサーバー側開発用の別のオプションとして導入することで、開発者はこの非常に人気のある言語を使用する利点を享受できます。fetch()コールを使用すると、データベース内から多くのタスクを実行できます。GETリクエストに制限されず、他のタスクも起動できます。

Oracle Database 23c Free-Developer Releaseでは、TLSで保護されたネットワーク・エンドポイントへのアクセスが大幅に簡素化されています。リソースの証明書をウォレットにインポートし、ローカルに格納する必要があるのではなく、かわりにオペレーティング・システムの証明書ストアを使用できます。