Skip to content

feat: add Body scope to ApisixRoute match expressions for request body matching#2762

Merged
AlinsRan merged 10 commits into
apache:masterfrom
AlinsRan:pr/body-scope-matching
May 13, 2026
Merged

feat: add Body scope to ApisixRoute match expressions for request body matching#2762
AlinsRan merged 10 commits into
apache:masterfrom
AlinsRan:pr/body-scope-matching

Conversation

@AlinsRan
Copy link
Copy Markdown
Contributor

@AlinsRan AlinsRan commented May 11, 2026

Summary

Add Body as a new scope value for ApisixRouteHTTPMatchExprSubject, enabling request body matching in ApisixRoute HTTP match expressions.

How it works

When scope: Body is used, the subject maps to APISIX's post_arg.<name> variable. This variable supports:

  • application/json
  • application/x-www-form-urlencoded
  • multipart/form-data

Dot-notation JSON path expressions are also supported (e.g., model.version, messages[*].role).

Example:

exprs:
- subject:
    scope: Body
    name: action        # matches form field or JSON key
  op: Equal
  value: login
exprs:
- subject:
    scope: Body
    name: model.version  # dot-notation JSON path
  op: Equal
  value: gpt-4

Changes

  • api/v2/shared_types.go: add ScopeBody = "Body" constant
  • api/v2/apisixroute_types.go:
    • Add case ScopeBody in ToVars() mapping to post_arg.<name>
    • Add Body to +kubebuilder:validation:Enum on Scope field
    • Add +kubebuilder:validation:XValidation CEL rule: name is required when scope is not Path
    • Make Name field optional (omitempty) so Path scope works without providing a name
  • api/v2/apisixroute_types_test.go: unit tests for Body scope and CEL validation
  • config/crd/bases/apisix.apache.org_apisixroutes.yaml: regenerated
  • docs/en/latest/reference/api-reference.md: regenerated
  • test/e2e/crds/v2/route.go: e2e tests for urlencoded form field and JSON nested path matching

Testing

Unit tests:

go test ./api/v2/... -run "TestToVars|TestCEL"

E2e tests added:

  • Test ApisixRoute match by body vars (urlencoded): POST form field action=login
  • Test ApisixRoute match by body vars (JSON nested path): POST JSON {"model": {"version": "gpt-4"}} with model.version dot-notation

AlinsRan added 10 commits May 11, 2026 08:59
…y matching

Add ScopeBody to ApisixRouteHTTPMatchExprSubject.Scope, which maps to
APISIX's post_arg.<name> variable. This supports request body matching
for application/json, application/x-www-form-urlencoded, and
multipart/form-data content types, and allows dot-notation JSON path
expressions such as 'model.version' and 'messages[*].role'.

Changes:
- Add ScopeBody constant to shared_types.go
- Add case ScopeBody in ToVars() mapping to post_arg.<name>
- Add +kubebuilder:validation:Enum=...;Body to Scope field
- Add +kubebuilder:validation:XValidation CEL rule: name is required
  when scope is not Path (uses size(self.name) > 0 for YAML safety)
- Make Name field optional (omitempty) so Path scope works without name
- Regenerate CRD YAML and API reference docs
- Add unit tests for Body scope (simple field, nested JSON path, empty name error)
- Add CEL expression tests (logic and CRD presence)
- Add e2e tests: urlencoded form field matching, JSON nested path matching

Closes apache#399
…dation

Replace the custom cel-go based tests with the same pattern used in
apisixconsumer_validation_test.go: load the generated CRD YAML, build
a real Kubernetes structural schema validator, and validate ApisixRoute
objects through it. This exercises both the OpenAPI enum constraints and
the CEL XValidation rule without introducing additional dependencies.
Move common CRD validation infrastructure (structural schema loading and
CEL validation) into crd_schema_validator_test.go so both
apisixconsumer_validation_test.go and apisixroute_types_test.go share
the same helper, eliminating the duplicate code flagged by golangci-lint.
@AlinsRan AlinsRan merged commit c99b26d into apache:master May 13, 2026
26 checks passed
@AlinsRan AlinsRan deleted the pr/body-scope-matching branch May 13, 2026 06:17
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.

3 participants