Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(trafiic-split): support rules based on json request body #11289

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

wilsonGen
Copy link

@wilsonGen wilsonGen commented May 24, 2024

Description

After this change, the traffic-split will be able to support rules based on json body in POST request. For example:
If we create a route like this:

{
   "methods": [
      "POST"
   ],
   "name": "Route based on json body (POST)",
   "uri": "/*",
   "plugins": {
      "traffic-split": {
         "rules": [
            {
               "match": [
                  {
                     "vars": [
                        [
                           "json_body_arg_$.cat.sounds_like",
                           "==",
                           "meow"
                        ]
                     ]
                  }
               ],
               "weighted_upstreams": [
                  {
                     "upstream": {
                        "nodes": {
                           "httpbin.org:80": 1
                        },
                        "type": "roundrobin"
                     },
                     "weight": 3
                  }
               ]
            }
         ]
      }
   },
   "upstream": {
      "nodes": {
         "google.com": 1
      },
      "type": "roundrobin"
   }
}

In traffic-split we defined "json_body_arg_cat.sounds_like" == "mewo", which means it will match the json body like this:

{
    "cat": {
        "sounds_like": "meow"
    },
    "other_fields": "hihi"
}

Motivation:
Currently the traffic-split plugin can create rules based on the default form of the POST request.
However it does not support rules based on application/json in the POST request body.
I think it will be great if it can support the rules based on json body as well.
As I have the need to have rules based on json body too.
Fixes # (issue)

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (If not, please discuss on the APISIX mailing list first)

@wilsonGen wilsonGen changed the title traffic split support rules based on json request body [feature]: traffic split support rules based on json request body May 24, 2024
@wilsonGen wilsonGen changed the title [feature]: traffic split support rules based on json request body feat(trafiic-split plugin): traffic split support rules based on json request body May 24, 2024
@shreemaan-abhishek shreemaan-abhishek changed the title feat(trafiic-split plugin): traffic split support rules based on json request body feat(trafiic-split): support rules based on json request body May 27, 2024
@shreemaan-abhishek
Copy link
Contributor

please add test cases and docs

@wilsonGen
Copy link
Author

I have added test cases and docs, please let me know if there are anything missing, thank you. 😃

"application/json") then
local arg_key = sub_str(key, 15)
local raw_request_body = request.get_body()
local body = cjson.decode(raw_request_body)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
local body = cjson.decode(raw_request_body)
local body, err = core.json.decode(raw_request_body)

local raw_request_body = request.get_body()
local body = cjson.decode(raw_request_body)
if body then
val = utils.get_nested_json_value(body, arg_key)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use jsonpath?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, just updated code using jsonpath, thank you. 😃

@wilsonGen wilsonGen force-pushed the traffic-split-support-rules-based-on-json-request-body branch from a38ffde to 5630aa7 Compare August 6, 2024 07:42
"application/json") then
local arg_key = sub_str(key, 15)
local raw_request_body = request.get_body()
local body, err = json.decode(raw_request_body)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using a cache, as this code may be executed multiple times on hot paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants