Apache APISIX Serverless Plugin 用于 Event Hooks
February 15, 2023
Apache APISIX は、Nginx 上に構築されたオープンソースの高性能な API ゲートウェイ です。その強力な機能の一つに、サーバーレス関数を作成する機能があります。サーバーレス関数は、Apache APISIX の機能を拡張するための小さなステートレスなプログラムです。この記事では、Apache APISIX の サーバーレス プラグイン の基本と、イベントに応じて サーバーレス関数 をトリガーする方法について説明します。
学習目標
この記事を通じて、以下の内容を学びます:
- Apache APISIX サーバーレスプラグインとは何か?
- サーバーレスプラグインの仕組みと使用方法
- サーバーレスプラグインのユースケース
- サーバーレスプラグインを使用して Webhook と統合する方法
Apache APISIX サーバーレスプラグインとは?
Apache APISIX の サーバーレス プラグインは、イベントフック用のサーバーレス関数を作成し、API ゲートウェイに統合することを可能にします。このプラグインは、イベントに応じてカスタムコードを実行するためのシンプルで柔軟な方法を提供し、基盤となるインフラストラクチャを管理する必要がありません。
サーバーレスプラグインは、イベント処理のロジックを個別のサーバーレス関数に分離することで、API アーキテクチャを簡素化し、管理を容易にします。Apache APISIX は、Azure Functions や AWS Lambda などの主要なクラウドベンダーのサーバーレスフレームワークをサポートしています。
サーバーレスプラグインの使用方法
Apache APISIX のサーバーレスプラグインを使用するには、Lua プログラミング言語でサーバーレス関数コードを記述し、イベントに応じて実行したいロジックを実装します。その後、リクエスト-レスポンスサイクルのフェーズに応じて serverless-pre-function
または serverless-post-function
プラグインを有効にします。
現在、APISIX は Lua のみをサポートしています。他のプログラミング言語を使用したい場合は、プラグインランナー を使用して新しい カスタムプラグイン を作成することができます。
サーバーレスプラグインのユースケース
以下に、Apache APISIX サーバーレスプラグインのユースケースをいくつか紹介します:
-
動的ルーティング: サーバーレスプラグインを使用して、リクエストメソッド、URL パス、ヘッダー値などの特定の基準に基づいて、受信した API リクエストを動的にルーティングすることができます。これにより、基盤となる Apache APISIX の設定を変更することなく、複雑なルーティングシナリオを簡単に実装できます。
-
認証と認可: サーバーレスプラグインを使用して、API の認証と認可チェックを実装できます。例えば、リクエストヘッダーに有効な API キーが含まれていることを確認するサーバーレス関数を作成し、リクエストを続行する前にチェックすることができます。また、forward-auth プラグインと組み合わせて、外部認可サービスとして使用することもできます。
-
リクエスト変換: サーバーレスプラグインを使用して、バックエンドサービスで処理される前に受信した API リクエストを変換することができます。例えば、バックエンドサービスが期待する形式にリクエストヘッダーやボディを変更するサーバーレス関数を作成できます。
-
レスポンス変換: サーバーレスプラグインを使用して、バックエンドサービスからのレスポンスをクライアントに返す前に変換することもできます。例えば、クライアントが期待する形式にレスポンスヘッダーやボディを変更するサーバーレス関数を作成できます。
-
ロギングとモニタリング: サーバーレスプラグインを使用して、API のロギングとモニタリングを実装できます。例えば、各 API リクエストの詳細情報(リクエストメソッド、URL、ヘッダー、ボディなど)をログに記録するサーバーレス関数を作成し、後で分析することができます。
Apache APISIX と Webhook の統合(デモ)
Apache APISIX を Webhook と統合するには、URL エンドポイントへの受信 POST リクエストをリッスンし、リクエストメソッドが POST であるかどうかを確認し、新しいメッセージが投稿されるたびにサードパーティサービスに Webhook 通知を送信するサーバーレス関数を作成する必要があります。
サーバーレス関数は、Webhook からのレスポンスも返す必要があります。これにより、Webhook のステータスやエラーメッセージを確認できます。どちらの場合も、APISIX はターゲットサービスと通信し、イベントがトリガーされたことを通知するために、指定された URL を呼び出します。
前提条件
プロジェクトのセットアップ
まず、GitHub から apisix-docker プロジェクトリポジトリをクローンします:
git clone https://github.com/apache/apisix-docker.git
プロジェクトフォルダを好きなコードエディタで開きます。このチュートリアルでは VS Code を使用します。
Apache APISIX のインストールと実行
Apache APISIX を実行するには、以下の手順に従います:
新しいターミナルウィンドウを開き、プロジェクトのルートフォルダから docker compose up
コマンドを実行します:
docker compose up -d
上記のコマンドは、Apache APISIX と etcd を Docker で一緒に実行します。
このデモでは Docker を使用して APISIX をインストールしましたが、インストールガイド には他のインストール方法も記載されています。
Apache APISIX でサーバーレス関数を設定する
Apache APISIX でサーバーレス関数を設定するには、エンドポイント用の新しい route を作成し、Lua で記述したカスタム関数コードを使用してサーバーレスプラグインを設定します。
以下は、エンドポイントへの受信 POST リクエストをリッスンし、Webhook 通知を送信する Lua でのサーバーレス関数の例です:
function webhook(conf, ctx)
-- 必要なライブラリをインポート
local http = require("resty.http")
local core = require("apisix.core")
-- リクエストメソッドが POST の場合のみ Webhook 通知を送信し、それ以外の場合は通常通りアップストリームに送信
if core.request.get_method() == "POST" then
-- 指定された URL に Webhook 通知を送信
local httpc = http.new()
local res, err = httpc:request_uri("http://webhook.site/9db3d3a0-ab64-4142-a39f-d4852ca50f8d", {
method = "POST",
headers = {
["Content-Type"] = "application/json"
},
body = core.request.get_body(),
})
-- Webhook からのレスポンスを確認
if not res then
core.log.error("Failed to send webhook: ", err)
return 500, err
end
end
-- アップストリームサービスからのレスポンスを返す
return conf.status, conf.body
end
上記のサンプル Webhook 関数コードでは、クライアントから API ゲートウェイへのリクエストボディをペイロードとして、指定された URL に JSON POST リクエストを送信します。Webhook エンドポイントをモックするために、https://webhook.site を使用しています。
Webhook エンドポイントを作成して設定するには:
- Web ブラウザで https://webhook.site にアクセスし、URL を生成します。
- Your unique URL の横にある Copy to clipboard を選択します。
- 関数コードの HTTP リクエストの
request_uri
メソッドに貼り付けます。
また、POST 以外のリクエストもすべてアップストリームサービスに転送されます。次のステップで、ルートとアップストリームを設定します。
ルートとアップストリームの設定
次に、サーバーレス関数プラグインを有効にした新しいルートと、バックエンドサービスとして機能するアップストリームを作成します。
curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-H 'Content-Type: application/json' \
-d '{
"uri": "/post",
"plugins": {
"serverless-pre-function": {
"phase": "rewrite",
"functions" : ["
return function(conf, ctx)
-- 必要なライブラリをインポート
local http = require(\"resty.http\")
local core = require(\"apisix.core\")
-- リクエストメソッドが POST の場合のみ Webhook 通知を送信し、それ以外の場合は通常通りアップストリームに送信
if core.request.get_method() == \"POST\" then
-- 指定された URL に Webhook 通知を送信
local httpc = http.new()
local res, err = httpc:request_uri(\"http://webhook.site/9db3d3a0-ab64-4142-a39f-d4852ca50f8d\", {
method = \"POST\",
headers = {
[\"Content-Type\"] = \"application/json\"
},
body = core.request.get_body(),
})
-- Webhook からのレスポンスを確認
if not res then
core.log.error(\"Failed to send webhook: \", err)
return 500, err
end
end
-- アップストリームサービスからのレスポンスを返す
return conf.status, conf.body
end"]
}
},
"upstream": {
"nodes": {
"httpbin.org:80": 1
},
"type": "roundrobin"
}
}'
上記のルート設定例では、APISIX の Admin API に curl
リクエストを送信して最初のルートを作成しました。ルートリクエストボディでは、/post
パスへのリクエストがサーバーレス関数コードをトリガーし、その後 httpbin.org
に転送されることを指定しています。これは、リクエストメソッドが POST であるかどうかを確認し、イベントをサードパーティサービスの Webhook エンドポイントに送信するかどうかを判断した後、リクエストが httpbin.org/post
エンドポイントにルーティングされることを意味します。バックエンドサービスは、あなたのバックエンドサービスに置き換えることができます。
また、serverless-pre-function
の functions
プロパティに関数コードを追加していることに気づくでしょう。
設定のテスト
最後に、/post
API ゲートウェイエンドポイントを呼び出して、すべてが期待通りに動作し、POST イベントが Webhook サイトに送信されるかどうかをテストします。
curl -i http://127.0.0.1:9080/post -X POST -d \
'{
"message": "A new webhook message"
}'
その後、前の手順で生成した Webhook URL にアクセスします。POST リクエストが表示され、イベントについて Webhook エンドポイントに通知され、リクエストボディが送信されているはずです。
さらに、モックアップストリームサービス httpbin.org
からのレスポンスも返されます:
HTTP/1.1 200 OK
Content-Type: application/json
{
...
"form": {
"{\n \"message\": \"A new webhook message\"\n}": ""
},
"headers": {
"Accept": "*/*",
"Content-Length": "41",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "127.0.0.1",
"X-Forwarded-Host": "127.0.0.1"
},
"json": null,
"url": "http://127.0.0.1/post"
}
明らかに、POST 以外の HTTP リクエストを送信した場合、サーバーレス関数コードは Webhook エンドポイントをトリガーしません。
これは、Apache APISIX でサーバーレス関数を設定する基本的な例です。Webhook に応じて別の関数をトリガーするなど、サーバーレス関数にさらに複雑なロジックを追加することで、この機能を拡張できます。
結論
Apache APISIX のサーバーレスプラグインは、API リクエストの処理中に発生するイベントに応じてサーバーレス関数をトリガーするための柔軟でスケーラブルな方法を提供します。このプラグインを使用することで、API アーキテクチャを簡素化し、サービスのパフォーマンスと信頼性を向上させ、アプリケーションインフラストラクチャの管理コストを削減できます。