Decorators Overview
Vovk.ts uses decorators to add metadata and behavior to controllers and their procedures.
HTTP Method Decorators
An HTTP method decorator sets the HTTP method and path of a procedure. It is the only decorator a procedure requires to be reachable over HTTP.
| Decorator | HTTP Method |
|---|---|
@get() | GET |
@post() | POST |
@put() | PUT |
@patch() | PATCH |
@del() | DELETE |
@head() | HEAD |
@options() | OPTIONS |
Each takes an optional path and an optional options object:
import { get, prefix, type VovkRequest } from 'vovk';
@prefix('users')
export default class UserController {
@get('{id}', { cors: true, headers: { 'x-custom': 'value' } })
static getUser(req: VovkRequest, { id }: { id: string }) {
return { id };
}
}Options:
cors?: boolean— adds CORS headers and answers OPTIONS, for the methods of that path that set it.headers?: Record<string, string>— custom response headers. See Response Headers for dynamic headers.staticParams?: Record<string, string>[]—@getonly: static params forgenerateStaticParams(). See Static Segment.before?: (req: VovkRequest) => unknown— runs on an HTTP request before the segment’sonBefore, the custom decorators and the handler, with the controller asthis; an error it throws becomes the response.
Auto-Generated Paths
Every HTTP decorator has an .auto() method that makes the path from the method name, in kebab-case:
export default class UserController {
// creates GET /api/get-all-users
@get.auto()
static getAllUsers() {
return [];
}
}With a params schema, .auto() also adds each param to the path: getUser with { id } becomes get-user/{id}.
@operation
Adds OpenAPI metadata to a procedure:
import { operation, get } from 'vovk';
export default class UserController {
@operation({ summary: 'Get user by ID', description: 'Returns a single user' })
@get('{id}')
static getUser() { /* ... */ }
}@operation.error() documents error responses, and @operation.tool() sets AI tool metadata.
Class Decorators
@prefix
Adds a path in front of every endpoint of a controller:
import { prefix, get } from 'vovk';
@prefix('users')
export default class UserController {
@get('{id}') // => GET /api/users/{id}
static getUser() { /* ... */ }
}@cloneControllerMetadata
Copies all metadata from a parent controller to a child class. Use it to reuse a controller in several segments:
import { prefix, cloneControllerMetadata } from 'vovk';
import UserController from './user-controller';
@cloneControllerMetadata()
@prefix('v2')
export default class UserControllerV2 extends UserController {}Custom Decorators
createDecorator builds your own middleware-style decorators for concerns that many procedures share, such as authentication, logging or caching. See the Custom Decorators page for the API and the Decorator Examples page for common patterns.
import { createDecorator, get, HttpException, HttpStatus, type VovkRequest } from 'vovk';
const authGuard = createDecorator(async (req: VovkRequest, next) => {
const token = req.headers.get('authorization');
if (!token) throw new HttpException(HttpStatus.UNAUTHORIZED, 'Missing token');
req.vovk.meta({ userId: await verifyToken(token) });
return next();
});
export default class UserController {
@get('{id}')
@authGuard()
static getUser(req: VovkRequest) {
const { userId } = req.vovk.meta();
// ...
}
}