rama_http/layer/json_rewrite/mod.rs
1//! Middleware that rewrites JSON request or response bodies on the fly, using
2//! rama's streaming JSON rewriter ([`rama_json::rewrite`]).
3//!
4//! [`JsonRewriteLayer`] wraps a service and, for each response, checks the
5//! `Content-Type`: an `application/json` or `application/*+json` body (that is
6//! not content-encoded) is piped through a
7//! [`JsonRewriter`](rama_json::rewrite::JsonRewriter) as it streams, applying
8//! a handler to matched values; anything else is forwarded unchanged. Because
9//! rewriting changes the body length, the layer drops the now-stale
10//! `Content-Length`.
11//! Handlers can replace or remove scalar values as well as whole object/array
12//! subtrees.
13//!
14//! [`JsonRequestRewriteLayer`] does the same for request bodies before the
15//! wrapped service sees the request.
16//!
17//! The body adapter, [`JsonRewriteBody`], is also usable on its own - e.g.
18//! composed with [`MapResponseBodyLayer`](crate::layer::map_response_body) or
19//! [`MapRequestBodyLayer`](crate::layer::map_request_body) -
20//! when you already handle the header concerns yourself.
21//!
22//! ## Handlers
23//!
24//! The handler is any type implementing
25//! [`JsonValueHandler`](rama_json::rewrite::JsonValueHandler). The layer
26//! requires it to be `Clone` (it is cloned per body, so each request/response
27//! rewrites with fresh handler state) and `Send`. A plain data struct fits
28//! naturally, since the rewriter is owned and only touched through `&mut self`
29//! while the body is polled.
30//!
31//! When the handler *accumulates* state, recover it once the body finishes
32//! via [`JsonRewriteBody::on_end`].
33//!
34//! ## Encoding
35//!
36//! The rewriter sees raw bytes, so a compressed (`Content-Encoding`) body is
37//! skipped. Place this layer *after* a decompression layer if you need to
38//! rewrite compressed requests or responses.
39
40mod body;
41mod service;
42
43pub use body::JsonRewriteBody;
44pub use service::{JsonRequestRewrite, JsonRequestRewriteLayer, JsonRewrite, JsonRewriteLayer};
45
46#[cfg(test)]
47mod tests;