Low-code programming platform for event-driven applications with visual flow-based editor and runtime system
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Express applications and HTTP server integration within Node-RED for building web interfaces, APIs, and HTTP-based nodes. Node-RED provides separate Express apps for editor administration and HTTP node functionality.
Express application serving the Node-RED editor interface and admin API endpoints.
/**
* Express application for editor interface and admin API
*/
const httpAdmin: express.Application;
/**
* Authentication middleware for admin routes
*/
interface AuthAPI {
needsPermission(permission: string): express.RequestHandler;
}Usage Examples:
const RED = require("node-red");
const express = require("express");
// Initialize Node-RED
await RED.start();
// Access admin app
const adminApp = RED.httpAdmin;
// Add custom admin routes
adminApp.get("/admin/status", RED.auth.needsPermission("read"), (req, res) => {
res.json({
version: RED.version,
uptime: process.uptime(),
flows: RED.runtime.flows.getFlows({}).length
});
});
// Add custom middleware to admin app
adminApp.use("/admin/custom", express.static("./public"));
// Integrate with existing Express app
const app = express();
app.use("/red", RED.httpAdmin);Express application for HTTP-based nodes (HTTP In, HTTP Response, etc.) and custom HTTP endpoints.
/**
* Express application for HTTP nodes and custom endpoints
*/
const httpNode: express.Application;Usage Examples:
const RED = require("node-red");
// Access HTTP node app
const nodeApp = RED.httpNode;
// Add custom API routes
nodeApp.get("/api/data", (req, res) => {
res.json({ data: "Custom API response" });
});
// Add middleware for HTTP nodes
nodeApp.use("/api", (req, res, next) => {
req.customData = "Added by middleware";
next();
});
// CORS configuration for HTTP nodes
nodeApp.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type");
next();
});
// Integrate with main app
const app = express();
app.use("/node-red", RED.httpNode);Direct access to the underlying HTTP server instance used by Node-RED.
/**
* HTTP server instance used by Node-RED
*/
const server: http.Server;Usage Examples:
const RED = require("node-red");
const WebSocket = require("ws");
// Access server instance
const server = RED.server;
// Add WebSocket server
const wss = new WebSocket.Server({ server });
wss.on('connection', (ws) => {
console.log('WebSocket client connected');
ws.on('message', (message) => {
console.log('Received:', message);
ws.send('Echo: ' + message);
});
});
// Get server information
console.log(`Server listening on port: ${server.address().port}`);
// Add server event listeners
server.on('upgrade', (request, socket, head) => {
console.log('HTTP upgrade request received');
});Patterns for creating HTTP-based nodes that integrate with Node-RED's HTTP infrastructure.
/**
* HTTP node registration pattern
*/
function HttpBasedNode(config) {
RED.nodes.createNode(this, config);
const node = this;
const path = config.path || "/api/mynode";
// Register HTTP endpoint
RED.httpNode.get(path, (req, res) => {
// Create message from HTTP request
const msg = {
_msgid: RED.util.generateId(),
req: req,
res: res,
payload: req.query,
topic: "http-request"
};
// Send to node's output
node.send(msg);
// Response will be sent by HTTP Response node
// or you can send response directly:
// res.json({ status: "ok" });
});
// Handle messages from flow
node.on('input', function(msg, send, done) {
// Process message and send HTTP response if res object exists
if (msg.res && !msg.res.headersSent) {
msg.res.json({
processed: msg.payload,
timestamp: Date.now()
});
}
done();
});
// Clean up routes on node removal
node.on('close', function(removed, done) {
// Remove HTTP routes (Node-RED handles this automatically)
done();
});
}Integration with Node-RED's authentication system for HTTP services.
/**
* Authentication methods
*/
interface AuthenticationAPI {
/** Check if user has specific permission */
needsPermission(permission: string): express.RequestHandler;
/** Extract user from request */
getUser(req: express.Request): UserObject | null;
}
/**
* Available permissions
*/
type Permission =
| "read" // Read access to editor and flows
| "write" // Write access to modify flows
| "*" // Full admin access
| "admin" // Administrative functions
| "audit"; // Audit log accessAuthentication Examples:
const RED = require("node-red");
// Protect admin routes
RED.httpAdmin.get("/admin/sensitive",
RED.auth.needsPermission("admin"),
(req, res) => {
res.json({ message: "Admin only data" });
}
);
// Protect HTTP node routes
RED.httpNode.get("/api/protected",
RED.auth.needsPermission("read"),
(req, res) => {
const user = RED.auth.getUser(req);
res.json({
message: "Protected data",
user: user ? user.username : "anonymous"
});
}
);
// Custom authentication middleware
RED.httpNode.use("/api/custom", (req, res, next) => {
const apiKey = req.headers['x-api-key'];
if (!apiKey || !validateApiKey(apiKey)) {
return res.status(401).json({ error: "Invalid API key" });
}
next();
});Serve static files through Node-RED's HTTP infrastructure.
/**
* Static file serving patterns
*/
// Serve static files from custom directory
RED.httpNode.use("/static", express.static("./public"));
// Serve files with caching headers
RED.httpNode.use("/assets", express.static("./assets", {
maxAge: "1d",
etag: true
}));
// Conditional static serving
RED.httpAdmin.use("/admin/assets", (req, res, next) => {
if (req.user && req.user.permissions.includes("admin")) {
express.static("./admin-assets")(req, res, next);
} else {
res.status(403).send("Forbidden");
}
});Configuration for secure HTTP services.
/**
* HTTPS configuration in settings
*/
interface HttpsSettings {
https: {
key: string | Buffer;
cert: string | Buffer;
ca?: string | Buffer;
passphrase?: string;
};
}HTTPS Example:
const fs = require("fs");
const RED = require("node-red");
// Initialize with HTTPS
RED.init({
https: {
key: fs.readFileSync("private-key.pem"),
cert: fs.readFileSync("certificate.pem")
},
uiPort: 1880
});
// Server will be HTTPS
RED.start().then(() => {
console.log("Node-RED started with HTTPS");
console.log("Editor: https://localhost:1880");
});Integration patterns for WebSocket communication alongside HTTP services.
/**
* WebSocket integration with Node-RED HTTP server
*/
const WebSocket = require("ws");
// Create WebSocket server using Node-RED's HTTP server
const wss = new WebSocket.Server({
server: RED.server,
path: "/ws"
});
// Handle WebSocket connections
wss.on('connection', (ws, req) => {
console.log('WebSocket connected from:', req.connection.remoteAddress);
// Integrate with Node-RED flows
ws.on('message', (data) => {
const msg = {
_msgid: RED.util.generateId(),
payload: JSON.parse(data),
topic: "websocket",
websocket: ws
};
// Send to flow (you would register this in a custom node)
// RED.events.emit("websocket-message", msg);
});
ws.on('close', () => {
console.log('WebSocket disconnected');
});
});const express = require("express");
const http = require("http");
const RED = require("node-red");
// Create Express app and HTTP server
const app = express();
const server = http.createServer(app);
// Initialize Node-RED
RED.init(server, {
httpAdminRoot: "/admin",
httpNodeRoot: "/api",
userDir: "./node-red-data",
uiPort: 3000
});
// Start Node-RED
RED.start().then(() => {
// Add custom routes
app.get("/", (req, res) => {
res.send("Node-RED Integration Example");
});
// Mount Node-RED apps
app.use("/admin", RED.httpAdmin);
app.use("/api", RED.httpNode);
// Start server
server.listen(3000, () => {
console.log("Server running on port 3000");
console.log("Node-RED editor: http://localhost:3000/admin");
console.log("Node-RED API: http://localhost:3000/api");
});
});interface UserObject {
username: string;
permissions: string[];
[key: string]: any;
}
interface HttpsSettings {
key: string | Buffer;
cert: string | Buffer;
ca?: string | Buffer;
passphrase?: string;
}