Skip to main content

HTTP Controllers

An HTTP controller is a class that groups related operations under a common base path. Each method on the class maps to an HTTP verb and path via @HttpOperation decorators. OPRA validates incoming requests and encodes responses automatically before your handler is ever called.


Defining a Controller

Decorate the class with @HttpController() and pass the base path for all operations in the controller.

import { HttpController } from '@opra/common';

@HttpController('/customers')
export class CustomersController {}

@HttpController() returns a chainable builder. Call additional methods on it to declare shared parameters, headers, cookies, and types that apply to every operation in the controller.

Declares a header that every operation in this controller accepts. OPRA validates and coerces the value before the handler runs.

@HttpController('/customers')
.Header('x-tenant-id', { type: 'string', required: true })
export class CustomersController {}

Access declared headers in the handler via ctx.request.headers.

Declares a cookie parameter shared across all operations.

@HttpController('/customers')
.Cookie('session', { type: 'string', required: true })
export class CustomersController {}

.QueryParam()

Declares a query parameter that applies to all operations. Useful for cross-cutting concerns such as locale, pagination defaults, or tenant context.

@HttpController('/customers')
.QueryParam('lang', { type: 'string' })
export class CustomersController {}

.PathParam()

Declares a path parameter shared by all operations — typically used when the controller itself is nested under a parameterised path segment.

@HttpController('/tenants/:tenantId/customers')
.PathParam('tenantId', { type: 'uid', required: true })
export class CustomersController {}

.KeyParam()

Declares the primary key parameter for the resource managed by this controller. KeyParam is used by entity operations — such as Get, Update, and Delete — to identify the target record.

@HttpController('/customers')
.KeyParam('id', { type: 'integer' })
export class CustomersController {}

.UseType()

Registers types with the controller scope so they are available in the schema without being declared globally in the ApiDocument. Useful for types that are only referenced within a single controller.

import { CustomerStatus } from '../models/enum/customer-status.js';

@HttpController('/customers')
.UseType(CustomerStatus)
export class CustomersController {}

Defining sub-controllers

A controller can nest child controllers under its base path using the controllers option. Each sub-controller is a fully independent controller with its own path, operations, and parameters.

import { HttpController } from '@opra/common';
import { OrdersController } from './orders.controller.js';
import { AddressesController } from './addresses.controller.js';

@HttpController('/customers', {
controllers: [OrdersController, AddressesController],
})
export class CustomersController {}

Sub-controller paths are resolved relative to the parent. OrdersController declared at /orders becomes accessible at /customers/orders.


Methods · Entity Method Templates