nfrankel commented on code in PR #1790:
URL: https://github.com/apache/apisix-website/pull/1790#discussion_r1580551778


##########
blog/en/blog/2024/05/02/pass-parameters-apisix.md:
##########
@@ -0,0 +1,296 @@
+---
+title: Five ways to pass parameters to Apache APISIX
+authors:
+  - name: Nicolas Fränkel
+    title: Author
+    url: https://github.com/nfrankel
+    image_url: https://avatars.githubusercontent.com/u/752258
+keywords:
+  - APISIX
+  - REST
+  - HTTP API
+description: >
+  I recently read 6 Ways To Pass Parameters to Spring REST API. Though the 
title is a bit misleading, as it's unrelated to REST, it does an excellent job 
listing all ways to send parameters to a Spring application. I want to do the 
same for Apache APISIX; it's beneficial when you write a custom plugin.
+tags: [Community]
+image: 
https://static.apiseven.com/uploads/2024/04/25/V05nSV5W_american-football-63109.jpg
+---
+
+<head>
+    <link rel="canonical" 
href="https://blog.frankel.ch/fix-duplicate-api-requests/"; />
+</head>
+
+>I recently read [6 Ways To Pass Parameters to Spring REST 
API](https://javabulletin.substack.com/p/6-ways-to-pass-parameters-to-spring). 
Though the title is a bit misleading, as it's unrelated to REST, it does an 
excellent job listing all ways to send parameters to a Spring application. I 
want to do the same for Apache APISIX; it's beneficial when you write a custom 
plugin.
+
+<!--truncate-->
+
+## General setup
+
+The general setup uses Docker Compose and static configuration.
+I'll have one plugin per way to pass parameters.
+
+```yaml
+services:
+  httpbin:
+    image: kennethreitz/httpbin                                         #1
+  apisix:
+    image: apache/apisix:3.9.0-debian
+    volumes:
+      - ./apisix/conf/config.yml:/usr/local/apisix/conf/config.yaml:ro
+      - ./apisix/conf/apisix.yml:/usr/local/apisix/conf/apisix.yaml:ro  #2
+      - ./apisix/plugins:/opt/apisix/plugins:ro                         #3
+    ports:
+      - "9080:9080"
+```
+
+1. Local httpbin for more reliable results and less outbound network traffic
+2. Static configuration file
+3. Plugins folder, one file per plugin
+
+```yaml
+deployment:
+  role: data_plane
+  role_data_plane:
+    config_provider: yaml                                              #1
+apisix:
+  extra_lua_path: /opt/?.lua                                           #2
+plugins:
+  - proxy-rewrite                                                      #3
+  - path-variables                                                     #4
+# ...  
+```
+
+1. Set static configuration
+2. Use every Lua file under `/opt/apisix/plugins` as a plugin
+3. Regular plugin
+4. Custom plugin, one per alternative
+
+## Path variables
+
+Path variables are a straightforward way to pass data. Their main issue is 
that they are limited to simple values, _e.g._, `/links/{n}/{offset}`. The 
naive approach is to write the following Lua code:
+
+```lua
+local core = require("apisix.core")
+
+function _M.access(_, ctx)
+    local captures, _ = ngx.re.match(ctx.var.uri, '/path/(.*)/(.*)')  --1-2
+    for k, v in pairs(captures) do
+        core.log.warn('Order-Value pair: ', k, '=', v)
+    end
+end
+```
+
+1. APISIX stores the URI in `ctx.var.uri`
+2. Nginx offers a regexp API
+
+Let's try:
+
+```bash
+curl localhost:9080/path/15/3
+```
+
+The log displays:
+
+```
+Order-Value pair: 0=/path/15/3
+Order-Value pair: 1=15
+Order-Value pair: 2=3
+```
+
+I didn't manage errors, though. Alternatively, we can rely on Apache APISIX 
features: a specific 
[router](https://apisix.apache.org/docs/apisix/terminology/router/). The 
default router, `radixtree_host_uri`, uses both the host and the URI to match 
requests. `radixtree_uri_with_parameter` lets go of the host part but also 
matches parameters.
+
+```yaml
+apisix:
+  extra_lua_path: /opt/?.lua
+  router:
+    http: radixtree_uri_with_parameter
+```
+
+We need to update the route:
+
+```yaml
+routes:
+  - path-variables
+  - uri: /path/:n/:offset                                              #1
+    upstream_id: 1
+    plugins:
+      path-variables: ~
+```
+
+1. Store `n` and `offset` in the context, under `ctx.curr_req_matched`
+
+We keep the plugin just to log the path variables:
+
+```lua
+function _M.access(_, ctx)
+    core.log.warn('n: ', ctx.curr_req_matched.n, ', offset: ', 
ctx.curr_req_matched.offset)
+end
+```
+
+The result is as expected with the same request as above:
+
+```
+n: 15, offset: 3
+```
+
+## Query parameters
+
+Query parameters are another regular way to pass data. Like path variables, 
you can only pass simple values, _e.g._, `/?foo=bar`. The Lua code doesn't 
require regexp:

Review Comment:
   I'll use regular expressions to avoid issues.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to