Node-RED JavaScript Processor
The Node-RED JavaScript processor allows you to write JavaScript code to process messages in a style similar to Node-RED function nodes. This makes it easy to port existing Node-RED functions to Benthos or write new processing logic using familiar JavaScript syntax.
Use the nodered_js
processor instead of the tag_processor
when you need full control over the payload and require custom processing logic that goes beyond standard tag or time series data handling. This processor allows you to write custom JavaScript code to manipulate both the payload and metadata, providing the flexibility to implement complex transformations, conditional logic, or integrate with other systems.
Configuration
pipeline:
processors:
- nodered_js:
code: |
// Your JavaScript code here
return msg;
Message Format
Messages in Benthos and in the JavaScript processor are handled differently:
In Benthos/Bloblang:
# Message content is the message itself
root = this # accesses the message content
# Metadata is accessed via meta() function
meta("some_key") # gets metadata value
meta some_key = "value" # sets metadata
In JavaScript (Node-RED style):
// Message content is in msg.payload
msg.payload // accesses the message content
// Metadata is in msg.meta
msg.meta.some_key // accesses metadata
The processor automatically converts between these formats.
Examples
Pass Through Message Input message:
{
"temperature": 25.5,
"humidity": 60
}
Metadata:
sensor_id: "temp_1"
location: "room_a"
JavaScript code:
pipeline:
processors:
- nodered_js:
code: |
// Message arrives as:
// msg.payload = {"temperature": 25.5, "humidity": 60}
// msg.meta = {"sensor_id": "temp_1", "location": "room_a"}
// Simply pass through
return msg;
Output: Identical to input
Modify Message Payload Input message:
["apple", "banana", "orange"]
JavaScript code:
pipeline:
processors:
- nodered_js:
code: |
// msg.payload = ["apple", "banana", "orange"]
msg.payload = msg.payload.length;
return msg;
Output message:
3
Create New Message Input message:
{
"raw_value": 1234
}
JavaScript code:
pipeline:
processors:
- nodered_js:
code: |
// Create new message with transformed data
var newMsg = {
payload: {
processed_value: msg.payload.raw_value * 2,
timestamp: Date.now()
}
};
return newMsg;
Output message:
{
"processed_value": 2468,
"timestamp": 1710254879123
}
Drop Messages (Filter) Input messages:
{"status": "ok"}
{"status": "error"}
{"status": "ok"}
JavaScript code:
pipeline:
processors:
- nodered_js:
code: |
// Only pass through messages with status "ok"
if (msg.payload.status === "error") {
return null; // Message will be dropped
}
return msg;
Output: Only messages with status "ok" pass through
Working with Metadata Input message:
{"value": 42}
Metadata:
source: "sensor_1"
JavaScript code:
pipeline:
processors:
- nodered_js:
code: |
// Add processing information to metadata
msg.meta.processed = "true";
msg.meta.count = "1";
// Modify existing metadata
if (msg.meta.source) {
msg.meta.source = "modified-" + msg.meta.source;
}
return msg;
Output message: Same as input
Output metadata:
source: "modified-sensor_1"
processed: "true"
count: "1"
Equivalent Bloblang:
meta processed = "true"
meta count = "1"
meta source = "modified-" + meta("source")
String Manipulation Input message:
"hello world"
JavaScript code:
pipeline:
processors:
- nodered_js:
code: |
// Convert to uppercase
msg.payload = msg.payload.toUpperCase();
return msg;
Output message:
"HELLO WORLD"
Numeric Operations Input message:
42
JavaScript code:
pipeline:
processors:
- nodered_js:
code: |
// Double a number
msg.payload = msg.payload * 2;
return msg;
Output message:
84
Logging Input message:
{
"sensor": "temp_1",
"value": 25.5
}
Metadata:
timestamp: "2024-03-12T12:00:00Z"
JavaScript code:
pipeline:
processors:
- nodered_js:
code: |
// Log various aspects of the message
console.log("Processing temperature reading:" + msg.payload.value);
console.log("From sensor:" + msg.payload.sensor);
console.log("At time:" + msg.meta.timestamp);
if (msg.payload.value > 30) {
console.warn("High temperature detected!");
}
return msg;
Output: Same as input, with log messages in Benthos logs
Performance Comparison
When choosing between Node-RED JavaScript and Bloblang for message processing, consider the performance implications. Here's a benchmark comparison of both processors performing a simple operation (doubling a number) on 1000 messages:
JavaScript Processing:
Median: 15.4ms
Mean: 20.9ms
Standard Deviation: 9.4ms
Range: 13.8ms - 39ms
Bloblang Processing:
Median: 3.7ms
Mean: 4ms
Standard Deviation: 800µs
Range: 3.3ms - 5.6ms
Key Observations:
Bloblang is approximately 4-5x faster for simple operations
Bloblang shows more consistent performance (smaller standard deviation)
However, considering typical protocol converter workloads (around 1000 messages/second), the performance difference is negligible for most use cases. The JavaScript processor's ease of use and familiarity often outweigh the performance benefits of Bloblang, especially for smaller user-generated flows.
Note that these benchmarks represent a simple operation. The performance difference may vary with more complex transformations or when using advanced JavaScript features.
Last updated