ExpressAdapter
ExpressAdapter integrates an OPRA ApiDocument into an Express application. It registers all controller routes on an Express Router, handles parameter and body decoding, dispatches to operation handlers, and serializes responses — all driven by the schema declarations.
Package: @opra/http
Extends: HttpAdapter
Constructor
new ExpressAdapter(app: Application, document: ApiDocument, options?: HttpAdapter.Options)
| Parameter | Type | Description |
|---|---|---|
app | express.Application | The Express application instance. |
document | ApiDocument | The OPRA document. Must expose an HttpApi (transport: 'http'). |
options | HttpAdapter.Options | Optional adapter configuration. |
Throws TypeError if document.api is not an HttpApi.
import express from 'express';
import { ExpressAdapter } from '@opra/http';
const app = express();
const adapter = new ExpressAdapter(app, document, {
basePath: '/api',
scope: 'public',
});
Properties
| Property | Type | Description |
|---|---|---|
app | express.Application | The Express application passed to the constructor. |
document | ApiDocument | The OPRA document. |
api | HttpApi | The HTTP API definition from the document. Shorthand for document.getHttpApi(). |
basePath | string | URL prefix for all OPRA routes. Defaults to '/'. |
scope | string | undefined | Validation scope applied to every request and response. |
interceptors | (InterceptorFunction | IHttpInterceptor)[] | Mutable interceptor chain. |
platform | string | Always 'express'. |
Methods
close()
close(): Promise<void>
Releases all controller instances created by the adapter. Call this during graceful shutdown.
process.on('SIGTERM', async () => {
await adapter.close();
process.exit(0);
});
getControllerInstance<T>()
getControllerInstance<T>(controllerPath: string): T | undefined
Returns the controller instance registered at the given path, or undefined if no controller matches. Useful for accessing controller state in tests or middleware.
| Parameter | Type | Description |
|---|---|---|
controllerPath | string | Path of the controller as declared in @HttpController({ path }). |
const ctrl = adapter.getControllerInstance<CustomersController>('/customers');
Interceptors
Interceptors are middleware-like functions that wrap every request. They run in declaration order before the operation handler is called.
Function form
import { HttpContext } from '@opra/http';
const adapter = new ExpressAdapter(app, document, {
interceptors: [
async (ctx: HttpContext, next) => {
const start = Date.now();
await next();
console.log(`${ctx.request.method} ${ctx.request.url} — ${Date.now() - start}ms`);
},
],
});
Class form
import { IHttpInterceptor, HttpContext } from '@opra/http';
import { UnauthorizedError } from '@opra/common';
class AuthInterceptor implements IHttpInterceptor {
async intercept(ctx: HttpContext, next: () => Promise<void>) {
const token = ctx.headers['authorization'];
if (!token) throw new UnauthorizedError();
ctx.locals.user = await verifyToken(token);
await next();
}
}
const adapter = new ExpressAdapter(app, document, {
interceptors: [new AuthInterceptor()],
});
Interceptors can also be added or removed at runtime by mutating adapter.interceptors.
Events
ExpressAdapter inherits from EventEmitter. Use adapter.on() to hook into the request lifecycle.
| Event | Payload | Emitted when |
|---|---|---|
'createContext' | HttpContext | A new HttpContext has been created, before interceptors run. |
'request' | HttpContext | The request enters the interceptor chain. |
'finish' | HttpContext | The response has been sent and the request lifecycle is complete. |
'error' | Error, HttpContext | An unhandled error occurred during request processing. |
adapter.on('finish', (ctx: HttpContext) => {
metrics.recordRequest(ctx.request.method, ctx.request.url, ctx.response.statusCode);
});
adapter.on('error', (err: Error, ctx: HttpContext) => {
logger.error({ err, url: ctx.request.url }, 'Unhandled request error');
});
Schema endpoint
The adapter automatically registers a schema endpoint at:
GET {basePath}/$schema
This endpoint returns the full ApiDocument serialized as JSON. No configuration is required.
GET /api/$schema → OpraSchema.ApiDocument
Interfaces
HttpAdapter.Options
Inherited from HttpAdapter.
| Option | Type | Default | Description |
|---|---|---|---|
basePath | string | '/' | URL prefix for all OPRA routes. |
scope | string | '*' | — | Validation scope applied to every request and response. '*' disables scope filtering. |
interceptors | (InterceptorFunction | IHttpInterceptor)[] | [] | Interceptor chain executed on every request. |