From 30711462e39398451a806a7486953cc57287e565 Mon Sep 17 00:00:00 2001 From: neu-hsc <67090824@qq.com> Date: Fri, 19 Jun 2026 13:17:30 +0800 Subject: [PATCH] docs: improve serverless function example --- docs/en/latest/plugins/serverless.md | 71 ++++++++++++---------------- docs/zh/latest/plugins/serverless.md | 71 ++++++++++++---------------- t/plugin/serverless.t | 53 +++++++++++++++++++++ 3 files changed, 113 insertions(+), 82 deletions(-) diff --git a/docs/en/latest/plugins/serverless.md b/docs/en/latest/plugins/serverless.md index 3df036eadb16..262d9e0b82af 100644 --- a/docs/en/latest/plugins/serverless.md +++ b/docs/en/latest/plugins/serverless.md @@ -88,9 +88,9 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"/ The examples below demonstrate how you can configure the `serverless-pre-function` and `serverless-post-function` plugins for different scenarios. -### Log Information before and after a Phase +### Set a Default Query Argument -The example below demonstrates how you can configure the serverless plugins to execute custom logics to log information to error logs before and after the `rewrite` [phase](../terminology/plugin.md#plugins-execution-lifecycle). +The example below demonstrates how you can configure a serverless pre-function to add a default `name` query argument during the `rewrite` [phase](../terminology/plugin.md#plugins-execution-lifecycle) when the client does not provide one. Create a Route as such: @@ -115,13 +115,7 @@ curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ "serverless-pre-function": { "phase": "rewrite", "functions" : [ - "return function() ngx.log(ngx.ERR, \"serverless pre function\"); end" - ] - }, - "serverless-post-function": { - "phase": "rewrite", - "functions" : [ - "return function(conf, ctx) ngx.log(ngx.ERR, \"match uri \", ctx.curr_req_matched and ctx.curr_req_matched._path); end" + "return function(conf, ctx) local core = require(\"apisix.core\"); local uri_args = core.request.get_uri_args(ctx); if not uri_args.name then uri_args.name = \"world\"; core.request.set_uri_args(ctx, uri_args); end end" ] } }, @@ -147,18 +141,16 @@ services: - /anything plugins: serverless-pre-function: - phase: rewrite - functions: - - | - return function() - ngx.log(ngx.ERR, "serverless pre function") - end - serverless-post-function: phase: rewrite functions: - | return function(conf, ctx) - ngx.log(ngx.ERR, "match uri ", ctx.curr_req_matched and ctx.curr_req_matched._path) + local core = require("apisix.core") + local uri_args = core.request.get_uri_args(ctx) + if not uri_args.name then + uri_args.name = "world" + core.request.set_uri_args(ctx, uri_args) + end end upstream: type: roundrobin @@ -206,20 +198,17 @@ metadata: spec: plugins: - name: serverless-pre-function - config: - phase: rewrite - functions: - - | - return function() - ngx.log(ngx.ERR, "serverless pre function") - end - - name: serverless-post-function config: phase: rewrite functions: - | return function(conf, ctx) - ngx.log(ngx.ERR, "match uri ", ctx.curr_req_matched and ctx.curr_req_matched._path) + local core = require("apisix.core") + local uri_args = core.request.get_uri_args(ctx) + if not uri_args.name then + uri_args.name = "world" + core.request.set_uri_args(ctx, uri_args) + end end --- apiVersion: gateway.networking.k8s.io/v1 @@ -278,20 +267,17 @@ spec: - name: httpbin-external-domain plugins: - name: serverless-pre-function - config: - phase: rewrite - functions: - - | - return function() - ngx.log(ngx.ERR, "serverless pre function") - end - - name: serverless-post-function config: phase: rewrite functions: - | return function(conf, ctx) - ngx.log(ngx.ERR, "match uri ", ctx.curr_req_matched and ctx.curr_req_matched._path) + local core = require("apisix.core") + local uri_args = core.request.get_uri_args(ctx) + if not uri_args.name then + uri_args.name = "world" + core.request.set_uri_args(ctx, uri_args) + end end ``` @@ -309,20 +295,23 @@ kubectl apply -f serverless-functions-ic.yaml -Send the request to the Route: +Send a request to the Route without the `name` query argument: ```shell curl -i "http://127.0.0.1:9080/anything" ``` -You should receive an `HTTP/1.1 200 OK` response and see the following entries in the error log: +You should receive an `HTTP/1.1 200 OK` response, and the response body should include: -```text -2024/05/09 15:07:09 [error] 51#51: *3963 [lua] [string "return function() ngx.log(ngx.ERR, "serverles..."]:1: func(): serverless pre function, client: 172.21.0.1, server: _, request: "GET /anything HTTP/1.1", host: "127.0.0.1:9080" -2024/05/09 15:16:58 [error] 50#50: *9343 [lua] [string "return function(conf, ctx) ngx.log(ngx.ERR, "..."]:1: func(): match uri /anything, client: 172.21.0.1, server: _, request: "GET /anything HTTP/1.1", host: "127.0.0.1:9080" +```json +{ + "args": { + "name": "world" + } +} ``` -The first entry is added by the pre-function and the second entry is added by the post-function. +The pre-function keeps an existing `name` query argument unchanged. For example, `curl -i "http://127.0.0.1:9080/anything?name=apisix"` should return `"name": "apisix"` in the response body. ### Register Custom Variables diff --git a/docs/zh/latest/plugins/serverless.md b/docs/zh/latest/plugins/serverless.md index 5ea73ab02631..d31b82c37590 100644 --- a/docs/zh/latest/plugins/serverless.md +++ b/docs/zh/latest/plugins/serverless.md @@ -88,9 +88,9 @@ admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"/ 以下示例演示如何在不同场景中配置 `serverless-pre-function` 和 `serverless-post-function` 插件。 -### 在阶段前后记录信息 +### 设置默认查询参数 -以下示例演示如何配置 serverless 插件,在 `rewrite` [阶段](../terminology/plugin.md#plugins-execution-lifecycle)之前和之后执行自定义逻辑,将信息记录到错误日志中。 +以下示例演示如何配置 serverless pre-function,在 `rewrite` [阶段](../terminology/plugin.md#plugins-execution-lifecycle)为未提供 `name` 查询参数的请求添加默认值。 创建如下路由: @@ -115,13 +115,7 @@ curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \ "serverless-pre-function": { "phase": "rewrite", "functions" : [ - "return function() ngx.log(ngx.ERR, \"serverless pre function\"); end" - ] - }, - "serverless-post-function": { - "phase": "rewrite", - "functions" : [ - "return function(conf, ctx) ngx.log(ngx.ERR, \"match uri \", ctx.curr_req_matched and ctx.curr_req_matched._path); end" + "return function(conf, ctx) local core = require(\"apisix.core\"); local uri_args = core.request.get_uri_args(ctx); if not uri_args.name then uri_args.name = \"world\"; core.request.set_uri_args(ctx, uri_args); end end" ] } }, @@ -147,18 +141,16 @@ services: - /anything plugins: serverless-pre-function: - phase: rewrite - functions: - - | - return function() - ngx.log(ngx.ERR, "serverless pre function") - end - serverless-post-function: phase: rewrite functions: - | return function(conf, ctx) - ngx.log(ngx.ERR, "match uri ", ctx.curr_req_matched and ctx.curr_req_matched._path) + local core = require("apisix.core") + local uri_args = core.request.get_uri_args(ctx) + if not uri_args.name then + uri_args.name = "world" + core.request.set_uri_args(ctx, uri_args) + end end upstream: type: roundrobin @@ -206,20 +198,17 @@ metadata: spec: plugins: - name: serverless-pre-function - config: - phase: rewrite - functions: - - | - return function() - ngx.log(ngx.ERR, "serverless pre function") - end - - name: serverless-post-function config: phase: rewrite functions: - | return function(conf, ctx) - ngx.log(ngx.ERR, "match uri ", ctx.curr_req_matched and ctx.curr_req_matched._path) + local core = require("apisix.core") + local uri_args = core.request.get_uri_args(ctx) + if not uri_args.name then + uri_args.name = "world" + core.request.set_uri_args(ctx, uri_args) + end end --- apiVersion: gateway.networking.k8s.io/v1 @@ -278,20 +267,17 @@ spec: - name: httpbin-external-domain plugins: - name: serverless-pre-function - config: - phase: rewrite - functions: - - | - return function() - ngx.log(ngx.ERR, "serverless pre function") - end - - name: serverless-post-function config: phase: rewrite functions: - | return function(conf, ctx) - ngx.log(ngx.ERR, "match uri ", ctx.curr_req_matched and ctx.curr_req_matched._path) + local core = require("apisix.core") + local uri_args = core.request.get_uri_args(ctx) + if not uri_args.name then + uri_args.name = "world" + core.request.set_uri_args(ctx, uri_args) + end end ``` @@ -309,17 +295,20 @@ kubectl apply -f serverless-functions-ic.yaml -向路由发送请求: +向路由发送不带 `name` 查询参数的请求: ```shell curl -i "http://127.0.0.1:9080/anything" ``` -你应该会收到 `HTTP/1.1 200 OK` 响应,并在错误日志中看到以下条目: +你应该会收到 `HTTP/1.1 200 OK` 响应,响应体中应包含如下内容: -```text -2024/05/09 15:07:09 [error] 51#51: *3963 [lua] [string "return function() ngx.log(ngx.ERR, "serverles..."]:1: func(): serverless pre function, client: 172.21.0.1, server: _, request: "GET /anything HTTP/1.1", host: "127.0.0.1:9080" -2024/05/09 15:16:58 [error] 50#50: *9343 [lua] [string "return function(conf, ctx) ngx.log(ngx.ERR, "..."]:1: func(): match uri /anything, client: 172.21.0.1, server: _, request: "GET /anything HTTP/1.1", host: "127.0.0.1:9080" +```json +{ + "args": { + "name": "world" + } +} ``` -第一条记录由 pre-function 添加,第二条记录由 post-function 添加。 +pre-function 会保留请求中已有的 `name` 查询参数。例如,`curl -i "http://127.0.0.1:9080/anything?name=apisix"` 应在响应体中返回 `"name": "apisix"`。 diff --git a/t/plugin/serverless.t b/t/plugin/serverless.t index e05ad6e1ae90..208c2106c15e 100644 --- a/t/plugin/serverless.t +++ b/t/plugin/serverless.t @@ -604,3 +604,56 @@ GET /hello --- error_code: 403 --- response_body chomp forbidden + + + +=== TEST 27: set route with serverless-pre-function to set default uri arg +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "serverless-pre-function": { + "phase": "rewrite", + "functions" : ["return function(conf, ctx) local core = require(\"apisix.core\"); local uri_args = core.request.get_uri_args(ctx); if not uri_args.name then uri_args.name = \"world\"; core.request.set_uri_args(ctx, uri_args); end end"] + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/print_request_received" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 28: serverless-pre-function sets default uri arg +--- request +GET /print_request_received +--- response_body_like +qr/request_uri: \/print_request_received\?name=world/ + + + +=== TEST 29: serverless-pre-function keeps existing uri arg +--- request +GET /print_request_received?name=apisix +--- response_body_like +qr/request_uri: \/print_request_received\?name=apisix/