Union Web Server Middleware
Union is a Node.js middleware kernel designed to provide a hybrid buffered and streaming approach to handling HTTP requests and responses. It aims for backward compatibility with `connect` middlewares, allowing existing `connect` applications to leverage its features. The current stable version is 0.6.0, last published over two years ago as of early 2024. The package's `engines` configuration (`node >= 0.8.0`) further indicates its age and lack of recent maintenance. Key differentiators include its streaming middleware architecture, which avoids buffering entire request streams, and its integration with the Flatiron ecosystem, notably with `director` for routing. Unlike standard `connect` middlewares, `union`'s response object emits a 'next' event for control flow, a pattern used by Flatiron-specific middlewares but not directly compatible in reverse with `connect`'s `next()` callback style.
Common errors
-
Error: listen EADDRINUSE :::9090
cause Another process is already using the port that the `union` server is attempting to listen on.fixEnsure no other application is running on the specified port, or choose a different port for your `union` server. On Linux/macOS, you can find processes using a port with `lsof -i :9090`. -
TypeError: connect is not a function
cause You are attempting to use the `connect` module in an incompatible way with a CommonJS context, or an incorrect version of `connect` is installed.fixEnsure `connect` is installed (`npm install connect@2`). If using `connect` v3+, it changed its API and might not be directly compatible without adapters. Also, `union` is CJS-only, so modern ESM `connect` versions will require specific interoperability layers if they even work. -
Error: Cannot find module 'director'
cause The `director` package, used in many `union` examples for routing, is not installed in your project.fixInstall the `director` package: `npm install director`.
Warnings
- breaking The `union` package is effectively abandoned and unmaintained. Its `package.json` specifies `node >= 0.8.0`, indicating compatibility with extremely old Node.js versions, and it has not been updated in over two years.
- gotcha Compatibility with `connect` middlewares is explicitly stated for `union 0.3.x` with `connect >= 2.1.0`. Later versions of `connect` (e.g., `3.x` or `2.x` versions not strictly `>= 2.1.0`) may not work as expected due to API changes.
- gotcha Union's response object (`res`) in middlewares uses `res.emit('next')` for control flow, a pattern specific to the Flatiron ecosystem. This is not reverse-compatible with standard `connect` middlewares that expect a `next()` callback as the third argument.
Install
-
npm install union -
yarn add union -
pnpm add union
Imports
- createServer
import { createServer } from 'union';const union = require('union'); const server = union.createServer({}); - union
import union from 'union';
const union = require('union'); - ResponseStream
const { ResponseStream } = require('union');const ResponseStream = union.ResponseStream;
Quickstart
const fs = require('fs');
const union = require('union');
const director = require('director');
const router = new director.http.Router();
const server = union.createServer({
before: [
function (req, res) {
const found = router.dispatch(req, res);
if (!found) {
res.emit('next'); // For Flatiron-compatible middlewares
}
}
]
});
router.get(/foo/, function () {
this.res.writeHead(200, { 'Content-Type': 'text/plain' });
this.res.end('hello world\n');
});
router.post(/foo/, { stream: true }, function () {
const req = this.req;
const res = this.res;
const writeStream = fs.createWriteStream(Date.now() + '-foo.txt');
req.pipe(writeStream);
writeStream.on('close', function () {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Wrote request body to a stream!');
});
});
server.listen(9090, () => {
console.log('Union server with director running on port 9090');
});
// To run this example, ensure 'director' is installed: npm install director