Skip to main content
Version: v4

HTTP API

The server global object is available in all Harper component code. It provides access to the HTTP server middleware chain, WebSocket server, authentication, resource registry, and cluster information.

server.http(listener, options)

Add a handler to the HTTP request middleware chain.

server.http(listener: RequestListener, options?: HttpOptions): HttpServer[]

Returns an array of HttpServer instances based on the options.port and options.securePort values.

Example:

server.http(
(request, next) => {
if (request.url === '/graphql') return handleGraphQLRequest(request);
return next(request);
},
{ runFirst: true }
);

RequestListener

type RequestListener = (request: Request, next: RequestListener) => Promise<Response>;

To continue the middleware chain, call next(request). To short-circuit, return a Response (or Response-like object) directly.

HttpOptions

PropertyTypeDefaultDescription
runFirstbooleanfalseInsert this handler at the front of the chain
portnumberhttp.portTarget the HTTP server on this port
securePortnumberhttp.securePortTarget the HTTPS server on this port

HttpServer

A Node.js http.Server or https.SecureServer instance.


Request

A Request object is passed to HTTP middleware handlers and direct static REST handlers. It follows the WHATWG Request API with additional Harper-specific properties.

Properties

PropertyTypeDescription
urlstringThe request target (path + query string), e.g. /path?query=string
methodstringHTTP method: GET, POST, PUT, DELETE, etc.
headersHeadersRequest headers
pathnamestringPath portion of the URL, without query string
protocolstringhttp or https
dataanyDeserialized body, based on Content-Type header
ipstringRemote IP address of the client (or last proxy)
hoststringHost from the request headers
sessionobjectCurrent cookie-based session (a Table record instance). Update with request.session.update({ key: value }). A cookie is set automatically the first time a session is updated or a login occurs.

Methods

request.login(username, password)

login(username: string, password: string): Promise<void>

Authenticates the user by username and password. On success, creates a session and sets a cookie on the response. Rejects if authentication fails.

sendEarlyHints(link: string, headers?: object): void

Sends an Early Hints (HTTP 103) response before the final response. Useful in cache resolution functions to hint at preloadable resources:

class Origin {
async get(request) {
this.getContext().requestContext.sendEarlyHints('<link rel="preload" href="/my-resource" as="fetch">');
return fetch(request);
}
}
Cache.sourcedFrom(Origin);

Low-Level Node.js Access

caution

These properties expose the raw Node.js request/response objects and should be used with caution. Using them can break other middleware handlers that depend on the layered Request/Response pattern.

PropertyDescription
_nodeRequestUnderlying http.IncomingMessage
_nodeResponseUnderlying http.ServerResponse

Response

REST method handlers can return:

  • Data directly — Serialized using Harper's content negotiation
  • A Response object — The WHATWG Response
  • A Response-like object — A plain object with the following properties:
PropertyTypeDescription
statusnumberHTTP status code (e.g. 200, 404)
headersHeadersResponse headers
dataanyResponse data, serialized via content negotiation
bodyBuffer | string | ReadableStream | BlobRaw response body (alternative to data)

server.ws(listener, options)

Add a handler to the WebSocket connection middleware chain.

server.ws(listener: WsListener, options?: WsOptions): HttpServer[]

Example:

server.ws((ws, request, chainCompletion) => {
chainCompletion.then(() => {
ws.on('message', (data) => console.log('received:', data));
ws.send('hello');
});
});

WsListener

type WsListener = (ws: WebSocket, request: Request, chainCompletion: Promise<void>, next: WsListener) => Promise<void>;
ParameterDescription
wsWebSocket instance
requestHarper Request object from the upgrade event
chainCompletionPromise that resolves when the HTTP request chain finishes. Await before sending to ensure the HTTP request is handled.
nextContinue chain: next(ws, request, chainCompletion)

WsOptions

PropertyTypeDefaultDescription
maxPayloadnumber100 MBMaximum WebSocket payload size
runFirstbooleanfalseInsert this handler at the front of the chain
portnumberhttp.portTarget the WebSocket server on this port
securePortnumberhttp.securePortTarget the secure WebSocket server on this port

server.upgrade(listener, options)

Add a handler to the HTTP server upgrade event. Use this to delegate upgrade events to an external WebSocket server.

server.upgrade(listener: UpgradeListener, options?: UpgradeOptions): void

Example (from the Harper Next.js component):

server.upgrade(
(request, socket, head, next) => {
if (request.url === '/_next/webpack-hmr') {
return upgradeHandler(request, socket, head).then(() => {
request.__harperdb_request_upgraded = true;
next(request, socket, head);
});
}
return next(request, socket, head);
},
{ runFirst: true }
);

When server.ws() is registered, Harper adds a default upgrade handler. The default handler sets request.__harperdb_request_upgraded = true after upgrading, and checks for this flag before upgrading again (so external upgrade handlers can detect whether Harper has already handled the upgrade).

UpgradeListener

type UpgradeListener = (request: IncomingMessage, socket: Socket, head: Buffer, next: UpgradeListener) => void;

UpgradeOptions

PropertyTypeDefaultDescription
runFirstbooleanfalseInsert at the front of the chain
portnumberhttp.portTarget the HTTP server on this port
securePortnumberhttp.securePortTarget the HTTPS server on this port

server.socket(listener, options)

Create a raw TCP or TLS socket server.

server.socket(listener: ConnectionListener, options: SocketOptions): SocketServer

Only one socket server is created per call. A securePort takes precedence over port.

ConnectionListener

Node.js connection listener as in net.createServer or tls.createServer.

SocketOptions

PropertyTypeDescription
portnumberPort for a net.Server
securePortnumberPort for a tls.Server

SocketServer

A Node.js net.Server or tls.Server instance.


server.authenticateUser(username, password)

Added in: v4.5.0

server.authenticateUser(username: string, password: string): Promise<User>

Returns the user object for the given username after verifying the password. Throws if the password is incorrect.

Use this when you need to explicitly verify a user's credentials (e.g., in a custom login endpoint). For lookup without password verification, use server.getUser().


server.getUser(username)

server.getUser(username: string): Promise<User>

Returns the user object for the given username without verifying credentials. Use for authorization checks when the user is already authenticated.


server.resources

The central registry of all resources exported for REST, MQTT, and other protocols.

server.resources.set(name, resource, exportTypes?)

Register a resource:

class NewResource extends Resource {}
server.resources.set('NewResource', NewResource);

// Limit to specific protocols:
server.resources.set('NewResource', NewResource, { rest: true, mqtt: false });

server.resources.getMatch(path, exportType?)

Find a resource matching a path:

server.resources.getMatch('/NewResource/some-id');
server.resources.getMatch('/NewResource/some-id', 'rest');

server.operation(operation, context?, authorize?)

Execute an Operations API operation programmatically.

server.operation(operation: object, context?: { username: string }, authorize?: boolean): Promise<any>
ParameterTypeDescription
operationobjectOperations API request body
context{ username: string }Optional: execute as this user
authorizebooleanWhether to apply authorization. Defaults to false.

server.recordAnalytics(value, metric, path?, method?, type?)

Record a metric into Harper's analytics system.

server.recordAnalytics(value: number, metric: string, path?: string, method?: string, type?: string): void
ParameterDescription
valueNumeric value (e.g. duration in ms, bytes)
metricMetric name
pathOptional URL path for grouping (omit per-record IDs — use the resource name)
methodOptional HTTP method for grouping
typeOptional type for grouping

Metrics are aggregated and available via the analytics API.


server.config

The parsed harperdb-config.yaml configuration object. Read-only access to Harper's current runtime configuration.


server.nodes

Returns an array of node objects registered in the cluster.

server.shards

Returns a map of shard number to an array of associated nodes.

server.hostname

Returns the hostname of the current node.

server.contentTypes

Returns the Map of registered content type handlers. Same as the global contentTypes object.


contentTypes

A Map of content type handlers for HTTP request/response serialization. Harper uses content negotiation: the Content-Type header selects the deserializer for incoming requests, and the Accept header selects the serializer for responses.

Built-in Content Types

MIME typeDescription
application/jsonJSON
application/cborCBOR
application/msgpackMessagePack
text/csvCSV
text/event-streamServer-Sent Events

Custom Content Type Handlers

Register or replace a handler by setting it on the contentTypes map:

import { contentTypes } from 'harperdb';

contentTypes.set('text/xml', {
serialize(data) {
return '<root>' + serialize(data) + '</root>';
},
q: 0.8, // quality: lower = less preferred during content negotiation
});

Handler Interface

PropertyTypeDescription
serialize(data)(any) => Buffer | Uint8Array | stringSerialize data for a response
serializeStream(data)(any) => ReadableStreamSerialize as a stream (for async iterables or large data)
deserialize(buffer)(Buffer | string) => anyDeserialize an incoming request body. Used when deserializeStream is absent. String for text/* types, Buffer for binary types.
deserializeStream(stream)(ReadableStream) => anyDeserialize an incoming request stream
qnumber (0–1)Quality indicator for content negotiation. Defaults to 1.