Pre-function Plugin 解説と実用サンプル
Kong Gatewayは多機能なAPIゲートウェイですが、ちょっとした処理をサーバレス関数として内蔵できることをご存知でしょうか?
今回は、Luaスクリプトを使ってリクエストのBodyからUUIDを抽出し、Headerに追記&ログ出力するという実用的なサンプルをご紹介します。
Pre-function Pluginとは?
公式ドキュメントにある通り、pre-function
プラグインはリクエストをAPIに送信する前にLuaで処理を記述できる柔軟な機能です。
用途は多彩で:
- 条件分岐によるフィルタリング
- ヘッダー/ボディのカスタマイズ
- 軽量ログやモニタリング処理
- メンテナンス用の簡易ブロック処理
など、プラグイン化するほどじゃないけど、ちょっと処理したいというニーズにぴったりです。
実用例
今回は、リクエストボディにあるUUIDを抽出してヘッダーとログに追記する機能をServer Less機能で実現します。
処理の流れ
- リクエストBodyからUUIDを抽出(JSONパース)
- UUIDがあれば
x-uuid
ヘッダーに追記 - 抽出結果をログに出力(File Logプラグイン使用)
前提準備:サービスとルートを作成
# サービス作成
curl -i -X POST http://localhost:8001/services \
--data name=mock-service \
--data url=http://httpbin.org/anything
# ルート作成
curl -i -X POST http://localhost:8001/services/mock-service/routes \
--data 'paths[]=/uuid-test'
File Log Plugin でログ出力(標準出力へ)
curl -i -X POST http://localhost:8001/services/mock-service/plugins \
--data "name=file-log" \
--data "config.path=/dev/stdout"
Pre-functionの設定
Nginxのフェーズ毎に、カスタムコードを実行することができます。フェーズに関する詳細内容は、以下をご参考ください。
https://nginx.org/en/docs/dev/development_guide.html#http_phases
curl -i -X POST http://localhost:8001/services/mock-service/plugins \
--data "name=pre-function" \
--data "config.access[1]=
local body, err, mimetype = kong.request.get_body()
if body.uuid ~= nil then
kong.service.request.add_header('uuid', body.uuid)
end
kong.service.request.enable_buffering()
kong.log.set_serialize_value('request.body', kong.request.get_body())" \
--data "config.log[1]=
kong.log.set_serialize_value('response.body', kong.service.response.get_body())"
上記のコードでは、access
フェーズとlog
フェーズに以下のコードを挿入しています。それぞれの意味をコメントで説明します。
-- リクエストからBodyを抽出
local body, err, mimetype = kong.request.get_body()
-- Bodyにあるuuidの存在を確認し、もしあったらHeaderに追加
if body.uuid ~= nil then
kong.service.request.add_header('uuid', body.uuid)
end
-- Bodyの内容をログに追加
kong.service.request.enable_buffering()
kong.log.set_serialize_value('request.body', kong.request.get_body())
-- レスポンスの内容をログに追加
kong.log.set_serialize_value('response.body', kong.service.response.get_body())
リクエスト送信
uuid
をBodyに設定してリクエストを送信します。
curl -i -X POST http://localhost:8000/uuid-test \
-H "Content-Type: application/json" \
-d '{"uuid": "123e4567-e89b-12d3-a456-426614174000"}'
すると、APIに到達した時、Headerに"Uuid": "123e4567-e89b-12d3-a456-426614174000"
が追加されています。
{
"args": {},
"data": "{\"uuid\": \"123e4567-e89b-12d3-a456-426614174000\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "48",
"Content-Type": "application/json",
"Host": "httpbin.org",
"Kong-Request-Id": "acfa1af0-c53e-4129-8b89-8a16be923e35",
"User-Agent": "curl/8.7.1",
"Uuid": "123e4567-e89b-12d3-a456-426614174000",
"X-Amzn-Trace-Id": "Root=1-67fe09a9-7b1c7cf96bbcc28938e75a7f",
"X-Forwarded-Host": "localhost",
"X-Forwarded-Path": "/uuid-test",
"X-Forwarded-Prefix": "/uuid-test",
"X-Kong-Request-Id": "ebfdfe72b011c1100130e00f026bfb65"
},
"json": {
"uuid": "123e4567-e89b-12d3-a456-426614174000"
},
"method": "POST",
"origin": "192.168.97.1, 133.201.15.64",
"url": "http://localhost/anything"
}
ログから、リクエストとレスポンスの詳細が表示されていて、Headerだけではなく、Bodyも確認できています。
{
...
"request": {
"uri": "/uuid-test",
"size": 187,
"method": "POST",
"querystring": {},
"body": {
"uuid": "123e4567-e89b-12d3-a456-426614174000"
},
"url": "http://localhost:8000/uuid-test",
"headers": {
"content-length": "48",
"user-agent": "curl/8.7.1",
"content-type": "application/json",
"host": "localhost:8000",
"accept": "*/*",
"kong-request-id": "acfa1af0-c53e-4129-8b89-8a16be923e35",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
},
"id": "ebfdfe72b011c1100130e00f026bfb65"
},
...
"response": {
"body": {
"origin": "192.168.97.1, 133.201.15.64",
"data": "{\"uuid\": \"123e4567-e89b-12d3-a456-426614174000\"}",
"json": {
"uuid": "123e4567-e89b-12d3-a456-426614174000"
},
"form": {},
"method": "POST",
"url": "http://localhost/anything",
"files": {},
"args": {},
"headers": {
"X-Forwarded-Host": "localhost",
"Content-Type": "application/json",
"Kong-Request-Id": "acfa1af0-c53e-4129-8b89-8a16be923e35",
"Uuid": "123e4567-e89b-12d3-a456-426614174000",
"X-Amzn-Trace-Id": "Root=1-67fe09a9-7b1c7cf96bbcc28938e75a7f",
"Accept": "*/*",
"Host": "httpbin.org",
"X-Kong-Request-Id": "ebfdfe72b011c1100130e00f026bfb65",
"User-Agent": "curl/8.7.1",
"X-Forwarded-Prefix": "/uuid-test",
"X-Forwarded-Path": "/uuid-test",
"Content-Length": "48"
}
},
"size": 1207,
"status": 200,
"headers": {
"via": "1.1 kong/3.10.0.0-enterprise-edition",
"x-kong-proxy-latency": "68",
"content-type": "application/json",
"x-kong-upstream-latency": "352",
"server": "gunicorn/19.9.0",
"content-length": "825",
"x-kong-request-id": "ebfdfe72b011c1100130e00f026bfb65",
"date": "Tue, 15 Apr 2025 07:24:25 GMT",
"access-control-allow-origin": "*",
"access-control-allow-credentials": "true",
"connection": "close"
}
},
...
}
まとめ
Kongのpre-functionとfile-logプラグインを組み合わせることで、外部サービスを呼ばずともAPIリクエスト内容の加工と可視化が実現できます。
Kongは単なるゲートウェイ以上に、「軽量なエッジ処理エンジン」として活用できます。Luaスクリプトをうまく使えば、REST APIの前処理をスマートに自動化できますよ!