json_body
Versions marked “overview” do not contain this page. Selecting one opens that version’s documentation overview.
On this page
Rewrites JSON request bodies with JSON Pointer add, remove, replace, and extract, and response bodies with remove and extract.
Configuration Notes
Applies mutating operations in one pass over a StreamBuffer-held body. Extract copies a pointer’s JSON into filter_metadata, structured metadata, or a request header without changing the body. filter_metadata values over 256 bytes are dropped; use structured metadata for nested or larger values. Extract promotion requires a single JSON value with only trailing whitespace after the document; non-whitespace trailing content blocks all extract destinations. Header values over 256 bytes or containing control characters are also skipped. Mutating pointers must not overlap (equal or prefix) within a direction. Duplicate extract pointers are rejected; nested extract pointers are allowed. Unused subtrees are copied as byte spans. Missing parents, missing replace/extract targets, and missing context values skip that operation (the original member is left unchanged). Duplicate object member names are not canonicalized. Remove drops every matching member. Replace and add-over-existing rewrite every matching member; add injects once only when no match exists. Extract keeps the last matching value. Add /- appends to arrays only; on an object the operation is skipped (same as a missing parent). Invalid JSON follows on_invalid ([OnInvalidBehavior]).
Extract-only directions are ReadOnly and defer extract until end of stream so promotion sees the full StreamBuffer body. Mixed extract and rewrite uses one walk; metadata-sourced add/replace resolve lazily at each splice site and are skipped when the extract value is not yet available.
Body signature preservation: extract-only directions never modify the body bytes, so upstream HMAC or signature checks remain valid. Directions with any mutating op (add, remove, replace) may alter inter-token whitespace even when the op has no runtime effect (e.g., a replace whose target is missing). Callers that need a stable body signature should not combine extract and mutating ops in the same direction; use a separate extract-only json_body filter earlier in the pipeline.
Response Content-Length is already committed when body hooks run. response_add and response_replace are rejected at config time. response_remove shrinks are padded with trailing spaces so the transferred byte count matches the committed Content-Length. This achieves redaction, not bandwidth reduction.
Content-type gating: when content_types is set, only bodies whose Content-Type matches one of the listed prefixes (case-insensitive) are processed; non-matching bodies pass through unchanged. When the list is empty (the default), all content types are processed. The compression filter has an equivalent knob.
Memory usage: peak heap per concurrent request is approximately 2 × max_body_bytes per mutating direction (the StreamBuffer input and the rewrite output coexist during the walk). Extract-only directions allocate no output buffer, so their peak is 1 × max_body_bytes. Size max_body_bytes for the workload, not the default.
Configuration
| Field | Type | Required | Description |
|---|---|---|---|
request_add | PointerOpConfig[] | no | Pointers to insert (or overwrite, for existing object keys) on the request body. |
request_add[].pointer | string | yes | JSON Pointer (RFC 6901) identifying the target. |
request_add[].value | any | no | Static JSON value (YAML maps to JSON). Mutually exclusive with the other sources. |
request_add[].metadata | string | no | filter_metadata key; injected as a JSON string. Mutually exclusive with the other sources. |
request_add[].structured_metadata | StructuredMetadataRef | no | Namespaced structured metadata; injected as JSON as-is. Mutually exclusive with the other sources. |
request_add[].structured_metadata.namespace | string | yes | Structured-metadata namespace. |
request_add[].structured_metadata.key | string | yes | Field within the namespace object. |
request_add[].env_var | string | no | Environment variable read once at filter construction. Mutually exclusive with the other sources. Valid JSON in the variable is injected as-is; otherwise the raw text is injected as a JSON string. |
request_remove | string[] | no | Pointers to omit from the request body. |
request_replace | PointerOpConfig[] | no | Pointers to overwrite on the request body when present. |
request_replace[].pointer | string | yes | JSON Pointer (RFC 6901) identifying the target. |
request_replace[].value | any | no | Static JSON value (YAML maps to JSON). Mutually exclusive with the other sources. |
request_replace[].metadata | string | no | filter_metadata key; injected as a JSON string. Mutually exclusive with the other sources. |
request_replace[].structured_metadata | StructuredMetadataRef | no | Namespaced structured metadata; injected as JSON as-is. Mutually exclusive with the other sources. |
request_replace[].structured_metadata.namespace | string | yes | Structured-metadata namespace. |
request_replace[].structured_metadata.key | string | yes | Field within the namespace object. |
request_replace[].env_var | string | no | Environment variable read once at filter construction. Mutually exclusive with the other sources. Valid JSON in the variable is injected as-is; otherwise the raw text is injected as a JSON string. |
request_extract | ExtractOpConfig[] | no | Pointers whose JSON is copied into request-scoped context. filter_metadata values are capped at 256 bytes by the context. Use structured_metadata for nested or larger values. Use header to promote into extra_request_headers (request extract only). |
request_extract[].pointer | string | yes | JSON Pointer (RFC 6901) identifying the value to copy. |
request_extract[].metadata | string | no | filter_metadata key to write. Mutually exclusive with the other destinations. JSON strings are stored decoded; other values are stored as their source JSON text. Values over 256 bytes are dropped by the context. |
request_extract[].structured_metadata | StructuredMetadataRef | no | Namespaced structured metadata to write. Mutually exclusive with the other destinations. |
request_extract[].structured_metadata.namespace | string | yes | Structured-metadata namespace. |
request_extract[].structured_metadata.key | string | yes | Field within the namespace object. |
request_extract[].header | string | no | Request header to promote the extracted value into. Mutually exclusive with the other destinations. JSON strings are promoted decoded; other values use their source JSON text. Values over 256 bytes or containing control characters are skipped. Not supported on response_extract. |
response_add | PointerOpConfig[] | no | Rejected when non-empty. Response add can grow the body after Content-Length is committed. |
response_add[].pointer | string | yes | JSON Pointer (RFC 6901) identifying the target. |
response_add[].value | any | no | Static JSON value (YAML maps to JSON). Mutually exclusive with the other sources. |
response_add[].metadata | string | no | filter_metadata key; injected as a JSON string. Mutually exclusive with the other sources. |
response_add[].structured_metadata | StructuredMetadataRef | no | Namespaced structured metadata; injected as JSON as-is. Mutually exclusive with the other sources. |
response_add[].structured_metadata.namespace | string | yes | Structured-metadata namespace. |
response_add[].structured_metadata.key | string | yes | Field within the namespace object. |
response_add[].env_var | string | no | Environment variable read once at filter construction. Mutually exclusive with the other sources. Valid JSON in the variable is injected as-is; otherwise the raw text is injected as a JSON string. |
response_remove | string[] | no | Pointers to omit from the response body. Shrinks are padded with trailing spaces so Content-Length still matches. |
response_replace | PointerOpConfig[] | no | Rejected when non-empty. Response replace can grow the body after Content-Length is committed. |
response_replace[].pointer | string | yes | JSON Pointer (RFC 6901) identifying the target. |
response_replace[].value | any | no | Static JSON value (YAML maps to JSON). Mutually exclusive with the other sources. |
response_replace[].metadata | string | no | filter_metadata key; injected as a JSON string. Mutually exclusive with the other sources. |
response_replace[].structured_metadata | StructuredMetadataRef | no | Namespaced structured metadata; injected as JSON as-is. Mutually exclusive with the other sources. |
response_replace[].structured_metadata.namespace | string | yes | Structured-metadata namespace. |
response_replace[].structured_metadata.key | string | yes | Field within the namespace object. |
response_replace[].env_var | string | no | Environment variable read once at filter construction. Mutually exclusive with the other sources. Valid JSON in the variable is injected as-is; otherwise the raw text is injected as a JSON string. |
response_extract | ExtractOpConfig[] | no | Pointers whose JSON is copied into request-scoped context from the response body. |
response_extract[].pointer | string | yes | JSON Pointer (RFC 6901) identifying the value to copy. |
response_extract[].metadata | string | no | filter_metadata key to write. Mutually exclusive with the other destinations. JSON strings are stored decoded; other values are stored as their source JSON text. Values over 256 bytes are dropped by the context. |
response_extract[].structured_metadata | StructuredMetadataRef | no | Namespaced structured metadata to write. Mutually exclusive with the other destinations. |
response_extract[].structured_metadata.namespace | string | yes | Structured-metadata namespace. |
response_extract[].structured_metadata.key | string | yes | Field within the namespace object. |
response_extract[].header | string | no | Request header to promote the extracted value into. Mutually exclusive with the other destinations. JSON strings are promoted decoded; other values use their source JSON text. Values over 256 bytes or containing control characters are skipped. Not supported on response_extract. |
content_types | string[] | no | Content-Type values that qualify for processing. A body whose Content-Type starts with any entry in this list is processed; other content types pass through unchanged. When empty (the default), all content types are processed. |
max_body_bytes | integer | no | Maximum body size in bytes for StreamBuffer mode. Peak heap is ~2× this value per mutating direction (input + output coexist); extract-only is ~1×. |
on_invalid | continue | reject | error | no | Behavior when the body is not valid JSON. |
Example
filter: json_body
content_types:
- application/json
request_extract:
- pointer: /model
metadata: original.model
- pointer: /stream
header: X-Stream
request_add:
- pointer: /tenant
value: acme
- pointer: /api_key
env_var: TENANT_API_KEY
- pointer: /original_model
metadata: original.model
request_remove:
- /password
request_replace:
- pointer: /model
value: forced-model
response_remove:
- /internal