English | 中文
Allows to create controller classes with methods as actions that handle requests. You can use routing-controllers with [express.js][1] or [koa.js][2].
npm install routing-controllers
reflect-metadata shim is required:npm install reflect-metadata
and make sure to import it before you use routing-controllers:
import 'reflect-metadata';
a. If you want to use routing-controllers with express.js, then install it and all required dependencies:
npm install express body-parser multer
Optionally you can also install their typings:
npm install -D @types/express @types/body-parser @types/multer
b. If you want to use routing-controllers with koa 2, then install it and all required dependencies:
npm install koa @koa/router koa-bodyparser @koa/multer
Optionally you can also install their typings:
npm install -D @types/koa @types/koa-bodyparser
npm install class-transformer class-validator
In prior versions, these were direct dependencies, but now they are peer dependencies so you can choose when to upgrade and accept breaking changes.
tsconfig.json file of your project:json
{
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
UserController.ts```typescript import 'reflect-metadata'; import { Controller, Param, Body, Get, Post, Put, Delete } from 'routing-controllers';
@Controller() export class UserController { @Get('/users') getAll() { return 'This action returns all users'; }
@Get('/users/:id')
getOne(@Param('id') id: number) {
return 'This action returns user #' + id;
}
@Post('/users')
post(@Body() user: any) {
return 'Saving user...';
}
@Put('/users/:id')
put(@Param('id') id: number, @Body() user: any) {
return 'Updating a user...';
}
@Delete('/users/:id')
remove(@Param('id') id: number) {
return 'Removing user...';
}
} ```
This class will register routes specified in method decorators in your server framework (express.js or koa).
app.ts```typescript // this shim is required import { createExpressServer } from 'routing-controllers'; import { UserController } from './UserController';
// creates express app, registers all controller routes and returns you express app instance const app = createExpressServer({ controllers: [UserController], // we specify controllers we want to use });
// run express application on port 3000 app.listen(3000); ```
if you are koa user you just need to use
createKoaServerinstead ofcreateExpressServer
http://localhost:3000/users. You will see This action returns all users in your browser.
If you open http://localhost:3000/users/1 you will see This action returns user #1.If you are designing a REST API where your endpoints always receive and return JSON then
you can use @JsonController decorator instead of @Controller.
This will guarantee you that data returned by your controller actions always be transformed to JSON
and Content-Type header will be always set to application/json.
It will also guarantee application/json header is understood from the requests and the body parsed as JSON:
import { JsonController, Param, Body, Get, Post, Put, Delete } from 'routing-controllers';
@JsonController()
export class UserController {
@Get('/users')
getAll() {
return userRepository.findAll();
}
@Get('/users/:id')
getOne(@Param('id') id: number) {
return userRepository.findById(id);
}
@Post('/users')
post(@Body() user: User) {
return userRepository.insert(user);
}
}
You can return a promise in the controller, and it will wait until promise resolved and return promise result in a response body.
import { JsonController, Param, Body, Get, Post, Put, Delete } from 'routing-controllers';
@JsonController()
export class UserController {
@Get('/users')
getAll() {
return userRepository.findAll();
}
@Get('/users/:id')
getOne(@Param('id') id: number) {
return userRepository.findById(id);
}
@Post('/users')
post(@Body() user: User) {
return userRepository.insert(user);
}
@Put('/users/:id')
put(@Param('id') id: number, @Body() user: User) {
return userRepository.updateById(id, user);
}
@Delete('/users/:id')
remove(@Param('id') id: number) {
return userRepository.removeById(id);
}
}
You can use framework's request and response objects directly. If you want to handle the response by yourself, just make sure you return the response object itself from the action.
import { Controller, Req, Res, Get } from 'routing-controllers';
@Controller()
export class UserController {
@Get('/users')
getAllUsers(@Req() request: any, @Res() response: any) {
return response.send('Hello response!');
}
@Get('/posts')
getAllPosts(@Req() request: any, @Res() response: any) {
// some response functions don't return the response object,
// so it needs to be returned explicitly
response.redirect('/users');
return response;
}
}
@Req() decorator injects you a Request object, and @Res() decorator injects you a Response object.
If you have installed typings, you can use their types:
import { Request, Response } from 'express';
import { Controller, Req, Res, Get } from 'routing-controllers';
@Controller()
export class UserController {
@Get('/users')
getAll(@Req() request: Request, @Res() response: Response) {
return response.send('Hello response!');
}
}
note: koa users can also use
@Ctx() contextto inject koa's Context object.
If you have, or if you want to create and configure express app separately,
you can use useExpressServer instead of createExpressServer function:
import { useExpressServer } from 'routing-controllers';
let express = require('express'); // or you can import it if you have installed typings
let app = express(); // your created express server
// app.use() // you can configure it the way you want
useExpressServer(app, {
// register created express server in routing-controllers
controllers: [UserController], // and configure it the way you need (controllers, validation, etc.)
});
app.listen(3000); // run your express server
koa users must use
useKoaServerinstead ofuseExpressServer
You can load all controllers from directories, by specifying array of directories in options of
createExpressServer or useExpressServer:
import { createExpressServer } from 'routing-controllers';
import path from 'path';
createExpressServer({
controllers: [path.join(__dirname + '/controllers/*.js')],
}).listen(3000); // register controllers routes in our express application
koa users must use
createKoaServerinstead ofcreateExpressServer
If you want to prefix all your routes, e.g. /api you can use routePrefix option:
import { createExpressServer } from 'routing-controllers';
import { UserController } from './controller/UserController';
createExpressServer({
routePrefix: '/api',
controllers: [UserController],
}).listen(3000);
koa users must use
createKoaServerinstead ofcreateExpressServer
You can prefix all specific controller's actions with base route:
@Controller('/users')
export class UserController {
// ...
}
You can use @Param decorator to inject parameters in your controller actions:
@Get("/users/:id")
getOne(@Param("id") id: number) { // id will be automatically casted to "number" because it has type number
}
If you want to inject all parameters use @Params() decorator.
To inject query parameters, use @QueryParam decorator:
@Get("/users")
getUsers(@QueryParam("limit") limit: number) {
}
You can use isArray option to get a query param array. This will cast the query param :
@Get("/users/by-multiple-ids")
getUsers(@QueryParam("ids", { isArray: true}) ids: string[]) {
}
GET /users/by-multiple-ids?ids=a → ids = ['a']
GET /users/by-multiple-ids?ids=a&ids=b → ids = ['a', 'b']
You can combine use isArray option with type option to get a query param array of one type. This will cast the query param :
@Get("/users/by-multiple-ids")
getUsers(@QueryParam("ids", { isArray: true, type: Number}) ids: number[]) {
}
GET /users/by-multiple-ids?ids=1 → ids = [1]
GET /users/by-multiple-ids?ids=1&ids=3.5 → ids = [1, 3.5]
If you want to inject all query parameters use @QueryParams() decorator.
The biggest benefit of this approach is that you can perform validation of the params.
enum Roles {
Admin = "admin",
User = "user",
Guest = "guest",
}
class GetUsersQuery {
@IsPositive()
limit: number;
@IsAlpha()
city: string;
@IsEnum(Roles)
role: Roles;
@IsBoolean()
isActive: boolean;
@IsArray()
@IsNumber(undefined, { each: true })
@Type(() => Number)
ids: number[];
}
@Get("/users")
getUsers(@QueryParams() query: GetUsersQuery) {
// here you can access query.role, query.limit
// and others valid query parameters
// query.ids will be an array, of numbers, even with one element
}
To inject request body, use @Body decorator:
@Post("/users")
saveUser(@Body() user: User) {
}
If you specify a class type to parameter t
$ claude mcp add routing-controllers \
-- python -m otcore.mcp_server <graph>