ForEach
When building an Atmo request handler or schedule, you can use the ForEach clause to iterate over an array of values, executing a Runnable on each element in the array.
1
- type: request
2
resource: /greetings
3
method: POST
4
steps:
5
- fn: set-array
6
as: names
7
8
- forEach:
9
in: names
10
fn: hello-name
11
as: greetings
Copied!
To use forEach, you must have a JSON array of objects in state. A simple array of strings or numbers is not currently supported, but is coming soon. The Runnable is called once for each element in the array, with the element added to the __elem state key.
In your Runnable's code, use req::state("__elem") to get the current array element being handled.
The example above takes the request body, saves it to the handler's state, and runs the hello-name Runable against each element, which changes all of the values. The result is then saved to the greetings key in state:
Input:
1
[
2
{
3
"name": "Connor"
4
},
5
{
6
"name": "Jimmy"
7
},
8
{
9
"name": "Bob"
10
}
11
]
Copied!
Output:
1
[
2
{
3
"name": "Hello Connor"
4
},
5
{
6
"name": "Hello Jimmy"
7
},
8
{
9
"name": "Hello Bob"
10
}
11
]
Copied!
Here's an example Rust runnable that can be called with forEach:
1
#[derive(Serialize, Deserialize)]
2
struct Elem {
3
name: String
4
}
5
6
struct HelloName{}
7
8
impl Runnable for HelloName {
9
fn run(&self, _: Vec<u8>) -> Result<Vec<u8>, RunErr> {
10
let elem_json = req::state_raw("__elem");
11
12
let mut elem: Elem = match serde_json::from_slice(elem_json.unwrap_or_default().as_slice()) {
13
Ok(e) => e,
14
Err(_) => return Err(RunErr::new(500, "failed to from_slice"))
15
};
16
17
elem.name = format!("Hello {}", elem.name);
18
19
Ok(serde_json::to_vec(&elem).unwrap_or_default())
20
}
21
}
Copied!
Last modified 2mo ago
Export as PDF
Copy link