configurapi-runner-ws
v1.20.1
Published
Websocket runner for configurapi.
Downloads
923
Readme
configurapi-runner-ws
This runner allows you to run Configurapi locally using a native Node.js WebSocket server.
It mirrors the behavior of configurapi-runner-lambda-ws, but runs
entirely on your local machine (or any Node.js host) without AWS.
Overview
- Use
Eventfor incoming WebSocket messages. - Use
Responsefor regular response data. - Use
StreamResponse(fromconfigurapi-handler-ws) for streaming responses. - Includes an optional HTTP management server.
Running Locally
Example:
const HttpRunner = require('configurapi-runner-ws');
const runner = new HttpRunner();
runner.run({
port: 8000,
configPath: './config.yaml'
});Default ports:
- HTTP:
8000 - HTTPS:
8443(ifkeyandcertprovided) - Management server:
9100
Streaming Responses
When returning a StreamResponse:
Data is delivered in chunks.
Each chunk includes:
x-stream: chunkThe final frame includes:
x-stream: doneEach stream includes:
x-stream-id: <id>
All chunks belonging to the same stream share the same x-stream-id.
The local runner supports backpressure handling using
ws.bufferedAmount.
Connection Lifecycle
on_connect
Triggered when a new WebSocket connection is established.
Use this event for:
- Authentication
- Authorization
- Protocol negotiation
If on_connect returns:
statusCode >= 400the connection is closed with:
1008 (Policy Violation)Example:
if (response.statusCode >= 400) {
ws.close(1008, 'Policy Violation');
}Sec-WebSocket-Protocol is automatically echoed back during
on_connect.
on_disconnect
Triggered when a WebSocket connection closes.
Use this for:
- Cleanup
- Resource release
- Logging
Request Object Details
Inside your Configurapi handler:
event.request.headers['connection-id']- Generated UUID for each WebSocket connection
event.request.headers['push-function']- Async function to send an out-of-band message to the same client
Example:
await event.request.headers['push-function'](
new Response({ hello: "world" }, 200)
);event.request.params- Available if provided in the client message
event.request.query- Comes from the WebSocket message body
event.request.payload- Only set if
payloadexists in the client message
- Only set if
If invalid JSON is received, the raw message is placed in payload.
Message Format Example
Client sends:
{
"name": "getData",
"params": { "id": 123 },
"payload": { "foo": "bar" },
"headers": {
"message-id": "abc-123"
}
}The runner:
- Creates a
Configurapi.Event - Routes to event
getData - Echoes
message-idin the response
Management Server
A management HTTP server runs on port 9100 by default. The postback URL can be found from event.request.headers['postback-url'].
Built-in internal routes:
list_@connections- Returns active WebSocket connection IDs
post_@connection- Sends a message to a specific connection
Example:
curl http://localhost:9100/list_@connectionsPost back to connection:
curl -X POST http://localhost:9100/post_@connection?id=<connectionId>Using wsPostbackFunction
You can also use wsPostbackFunction directly when communicating through the local HTTP management bridge.
The postback URL can be found from event.request.headers['postback-url'].
Import:
const { wsPostbackFunction } = require('configurapi-runner-ws');Example:
await wsPostbackFunction(
`http://localhost:9100/@connections/${connectionId}`,
{
statusCode: 200,
headers: { 'message-id': '123' },
body: { message: 'Hello' }
}
);Error Handling
SyntaxError→ 400- All other errors → 500
message-idheader is preserved in error responses
HTTPS Support
If key and cert are provided:
runner.run({
sPort: 8443,
key: fs.readFileSync('./server.key'),
cert: fs.readFileSync('./server.cert')
});the server runs securely over HTTPS + WSS.
Transport Differences from Lambda Runner
Local Runner Lambda Runner
Uses native WebSocket Uses API Gateway WebSocket
Close with 1008 for connect Return HTTP 4xx/5xx from $connect
rejection
Backpressure via Frame queue with retry logic
ws.bufferedAmount
Direct ws.send() API Gateway postToConnection()
Functionally, both runners behave the same at the Configurapi level.
Best Practices
- Use
on_connectfor authentication. - Always include
namein client messages. - Use
StreamResponsefor progressive or large responses. - Monitor active connections via the management server.
