How is mutability for headers implemented in the Rhai plugin system? #2632
-
I've been playing with Rhai plugins and think I'm getting the hang of it. However, looking at the implementation Let's imagine I'm modifying headers in the
What I don't understand is how you manage to capture all the modifications the Rhai functions do to the headers in step 2, in order to have them ready for step 3. There's a getter implemented for headers on the request // Originating Request
$engine.register_get(
"headers",
|obj: &mut SharedMut<$base::Request>| -> Result<HeaderMap, Box<EvalAltResult>> {
Ok(obj.with_mut(|request| request.supergraph_request.headers().clone()))
}
); and there's also the indexer for .register_indexer_set(|x: &mut HeaderMap, key: &str, value: &str| {
x.insert(
HeaderName::from_str(key).map_err(|e| e.to_string())?,
HeaderValue::from_str(value).map_err(|e| e.to_string())?,
);
Ok(())
}) But the getter returns a clone of I know how to make it so that Rhai functions actually mutate a Rust struct in place, by registering functions that operate on What am I missing? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
I had trouble understanding this at first, too. What makes this work is a perhaps-surprising feature of Rhai called chaining updates. In this Rhai code:
… what happens in terms of Rust code is:
$engine.register_set(
"headers",
|obj: &mut SharedMut<$base::Request>, headers: HeaderMap| {
if_subgraph! {
$base => {
let _unused = (obj, headers);
Err("cannot mutate originating request on a subgraph".into())
} else {
obj.with_mut(|request| *request.supergraph_request.headers_mut() = headers);
Ok(())
}
}
}
); (Which by the way shows that the Rhai script above would fail if it were running at the subgraph stage, see https://www.apollographql.com/docs/router/customizations/rhai-api#request-interface) Why this question? Are you looking into using Rhai in another project? |
Beta Was this translation helpful? Give feedback.
I had trouble understanding this at first, too. What makes this work is a perhaps-surprising feature of Rhai called chaining updates. In this Rhai code:
… what happens in terms of Rust code is:
headers
onsubgraph::Request
is called, returning a clonedHeaderMap
HeaderMap
is called with a key and new value. This modifies the cloned map but not (yet) the request.headers
onsubgraph::Request
with the mutatedHeaderMap
. The bindings for that one are: