Skip to main content

HttpAdapter

HttpAdapter is the abstract base class for all HTTP platform adapters. It manages the interceptor chain, base path, scope, and request processing — including context creation, parsing, dispatch, response serialization, and bundle handling.

import { HttpAdapter } from '@opra/http';

Extends: PlatformAdapter

You do not instantiate HttpAdapter directly. Extend ExpressAdapter or implement your own platform adapter subclass.


Properties

PropertyTypeDescription
transform'http'Always 'http'. Identifies the transport type.
basePathstringURL prefix prepended to all OPRA routes. Defaults to '/'.
scopestring | undefinedValidation scope applied to every request and response.
interceptors(InterceptorFunction | IHttpInterceptor)[]Mutable interceptor chain executed on every request.
apiHttpApiThe HTTP API definition from the document. Shorthand for document.getHttpApi().

Abstract methods

handleRawRequest

abstract handleRawRequest(req: http.IncomingMessage, res: http.ServerResponse): Promise<void>

Entry point for the platform adapter implementation. Subclasses (e.g. ExpressAdapter) implement this to receive raw Node.js request/response objects, resolve the matching controller and operation, and call handleRequest with the constructed context.


Methods

createContext

createContext(
req: http.IncomingMessage,
res: http.OutgoingMessage,
args?: {
controller?: HttpController;
controllerInstance?: any;
operation?: HttpOperation;
operationHandler: Function;
}
): Promise<HttpContext>

Creates an HttpContext from raw Node.js request/response objects. Upgrades req to an HttpRequest and res to an HttpResponse, then emits the 'create-context' event before returning.

Called by handleRawRequest implementations. You rarely need to call this directly.


handleRequest

handleRequest(context: HttpContext): Promise<void>

Main request processing pipeline. Sets OPRA response headers, runs parseRequest, fires the 'request' event, executes the interceptor chain, calls the operation handler via sendResponse, and emits 'finish'. On error, wraps the exception with wrapException and sends an error response.


handleBundle

handleBundle(bundle: HttpBundle): Promise<void>

Processes a bundle request — a multipart/mixed request where each part is a complete HTTP sub-request. Each sub-request is parsed and dispatched independently via handleRawRequest, and the sub-responses are collected and returned as a single multipart/mixed response. Part-level X-Request-Id headers are preserved in the response parts for correlation.

Throws BadRequestError if the request Content-Type is not multipart/mixed.

// Bundle requests are typically handled transparently by ExpressAdapter.
// Each part of the multipart body is a raw HTTP request:
// POST /api/$bundle HTTP/1.1
// Content-Type: multipart/mixed; boundary=---boundary
//
// -----boundary
// Content-Type: application/http
// X-Request-Id: req-1
//
// GET /api/customers HTTP/1.1
// ...

parseRequest

parseRequest(context: HttpContext): Promise<void>

Decodes all declared parameters (cookies, headers, path, query) and validates the Content-Type against the operation's .RequestContent() declaration. Sets the default response status code from the first declared 2xx response.


sendResponse

sendResponse(context: HttpContext, responseValue?: any): Promise<void>

Serializes and sends the response. Validates and encodes the body against the declared HttpOperationResponse type. Handles OperationResult wrapping, content-type negotiation, composition-based payload shaping (e.g. Entity.FindMany), and error fallback.


sendDocumentSchema

sendDocumentSchema(context: HttpContext): Promise<void>

Responds with the full ApiDocument serialized as JSON. Used by the GET {basePath}/$schema endpoint. Supports an optional ?id= query parameter to return a sub-document.


Interfaces

HttpAdapter.Options

OptionTypeDefaultDescription
basePathstring'/'URL prefix for all OPRA routes.
scopestring | '*'Validation scope applied to every request and response. '*' disables scope filtering.
interceptors(InterceptorFunction | IHttpInterceptor)[][]Interceptor chain executed on every request.

HttpAdapter.ResponseArgs

Internal shape used to carry resolved response metadata before the response is sent.

PropertyTypeDescription
statusCodenumberHTTP status code to send.
contentTypestring | undefinedResolved Content-Type value.
operationResponseHttpOperationResponse | undefinedThe matched HttpOperationResponse declaration.
bodyanyThe response body after encoding.
projectionstring[] | '*' | undefinedField projection applied during encoding.

HttpAdapter.IHttpInterceptor

type IHttpInterceptor = {
intercept(context: HttpContext, next: NextCallback): Promise<void>;
};

Class-based interceptor interface. Implement intercept to wrap request processing.


HttpAdapter.InterceptorFunction

type InterceptorFunction = (context: HttpContext, next: NextCallback) => Promise<void>;

Function-based interceptor. Equivalent to IHttpInterceptor['intercept'].


HttpAdapter.NextCallback

type NextCallback = () => Promise<void>;

Async function passed to interceptors. Call await next() to continue to the next interceptor or the operation handler.


HttpAdapter.Events

Events are grouped into three sets: adapter-level, per-context lifecycle, and per-bundle lifecycle.

Adapter events

EventPayloadEmitted when
'create-context'ctx: HttpContextA new HttpContext has been created, before interceptors run.
'request'ctx: HttpContextThe request enters the interceptor chain.
'error'error: Error, ctx?: HttpContextAn unhandled error occurred during request processing.

Per-context lifecycle events (fired for every request, including sub-requests inside a bundle)

EventPayloadEmitted when
'context-before-execute'ctx: HttpContextImmediately before the operation handler is called.
'context-after-execute'responseValue: any, ctx: HttpContextAfter the operation handler returns successfully.
'context-finish'ctx: HttpContextContext lifecycle complete. Always fires.

Per-bundle lifecycle events (fired only for multipart/mixed batch requests)

EventPayloadEmitted when
'bundle-before-execute'bundle: HttpBundleBefore the first sub-request in the batch starts.
'bundle-after-execute'bundle: HttpBundleAfter all sub-requests complete successfully.
'bundle-finish'bundle: HttpBundleBundle lifecycle complete. Always fires.
// Adapter-level tracing across all requests
adapter.on('context-before-execute', ctx => {
ctx['_traceStart'] = Date.now();
});

adapter.on('context-finish', ctx => {
const ms = Date.now() - ctx['_traceStart'];
console.log(`${ctx.request.method} ${ctx.request.url}${ms}ms`);
});

// Bundle-level transaction logging
adapter.on('bundle-finish', bundle => {
const status = bundle.success ? 'committed' : 'rolled back';
console.log(`Batch ${status} (${bundle.size} requests)`);
});