Controller Mapping
Map OpenAPI operations to controller methods using the x-controller and x-action extensions.
Extension Reference
| Extension | Type | Description |
|---|---|---|
| x-controller | string | Path to the controller file (relative to server.controllers) |
| x-action | string | Method name to invoke on the controller |
Controllers are resolved through the IoC container, allowing full dependency injection:
// server/controller/user.ts
import { Component, Inject } from '@noego/ioc';
import { Request, Response } from 'express';
import { UserService } from '../service/user';
@Component()
export class UserController {
constructor(
@Inject(UserService) private userService: UserService
) {}
async list(req: Request, res: Response) {
const users = await this.userService.findAll();
res.json(users);
}
async getById(req: Request, res: Response) {
const user = await this.userService.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
}
async update(req: Request, res: Response) {
const user = await this.userService.update(req.params.id, req.body);
res.json(user);
}
}Nested Controllers
Controllers can be nested inside folders. The x-controller value uses forward slashes to reflect the folder structure under the server.controllers root.
Example: if server.controllers is src/server/controller, then billing/invoice.controller resolves to src/server/controller/billing/invoice.controller.ts.
module:
billing:
basePath: /api/billing
paths:
/invoices/{id}:
get:
x-controller: billing/invoice.controller
x-action: get
summary: Get invoiceMiddleware
Controllers are invoked after any route middleware has run. Keep this page focused on controller mapping; middleware declarations, resolution rules, named exports, and test patterns are covered in the dedicated guide.
Read the Dinner middleware guide