MCPcopy Index your code
hub / github.com/typestack/routing-controllers

github.com/typestack/routing-controllers @v0.11.3 sqlite

repository ↗ · DeepWiki ↗ · release v0.11.3 ↗
818 symbols 1,783 edges 211 files 77 documented · 9% 1 cross-repo links
README

routing-controllers

Build Status codecov npm version Dependency Status

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].

Table of Contents

Installation

  1. Install module:

npm install routing-controllers

  1. reflect-metadata shim is required:

npm install reflect-metadata

and make sure to import it before you use routing-controllers:

import 'reflect-metadata';
  1. Install framework:

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

  1. Install peer dependencies:

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.

  1. Its important to set these options in tsconfig.json file of your project:

json { "emitDecoratorMetadata": true, "experimentalDecorators": true }

Example of usage

  1. Create a file 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).

  1. Create a file 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 createKoaServer instead of createExpressServer

  1. Open in browser 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.

More examples

Working with json

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);
  }
}

Return promises

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);
  }
}

Using Request and Response objects

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() context to inject koa's Context object.

Pre-configure express/koa

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 useKoaServer instead of useExpressServer

Load all controllers from the given directory

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 createKoaServer instead of createExpressServer

Prefix all controllers routes

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 createKoaServer instead of createExpressServer

Prefix controller with base route

You can prefix all specific controller's actions with base route:

@Controller('/users')
export class UserController {
  // ...
}

Inject routing parameters

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.

Inject query parameters

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=aids = ['a'] GET /users/by-multiple-ids?ids=a&ids=bids = ['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=1ids = [1] GET /users/by-multiple-ids?ids=1&ids=3.5ids = [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
}

Inject request body

To inject request body, use @Body decorator:

@Post("/users")
saveUser(@Body() user: User) {
}

If you specify a class type to parameter t

Extension points exported contracts — how you extend this code

InterceptorInterface (Interface)
(no doc) [8 implementers]
src/InterceptorInterface.ts
KoaMiddlewareInterface (Interface)
(no doc) [23 implementers]
src/driver/koa/KoaMiddlewareInterface.ts
IPayload (Interface)
(no doc)
sample/sample17-controllers-inheritance/interface/IPayload.ts
BlogFilter (Interface)
(no doc)
sample/sample4-extra-parameters/BlogController.ts
RoleChecker (Interface)
(no doc)
src/RoleChecker.ts
Action (Interface)
(no doc)
src/Action.ts
CustomParameterDecorator (Interface)
(no doc)
src/CustomParameterDecorator.ts
UseContainerOptions (Interface)
(no doc)
src/container.ts

Core symbols most depended-on inside this repo

Get
called by 164
src/decorator/Get.ts
get
called by 162
src/container.ts
getMetadataArgsStorage
called by 104
src/index.ts
JsonController
called by 53
src/decorator/JsonController.ts
Post
called by 51
src/decorator/Post.ts
createExpressServer
called by 47
src/index.ts
reset
called by 43
test/fakes/global-options/FakeService.ts
Req
called by 33
src/decorator/Req.ts

Shape

Method 399
Class 315
Function 76
Interface 28

Languages

TypeScript100%

Modules by API surface

test/functional/action-params.spec.ts51 symbols
test/functional/controller-methods.spec.ts29 symbols
test/functional/express-error-handling.spec.ts23 symbols
test/functional/express-middlewares.spec.ts20 symbols
test/functional/interceptors.spec.ts19 symbols
src/metadata-builder/MetadataBuilder.ts18 symbols
test/functional/other-controller-decorators.spec.ts17 symbols
src/driver/koa/KoaDriver.ts16 symbols
src/driver/express/ExpressDriver.ts16 symbols
test/functional/json-controller-methods.spec.ts15 symbols
test/functional/container.spec.ts14 symbols
test/functional/middlewares-order.spec.ts12 symbols

Used by 1 indexed graphs manifest dependencies, hub-wide

Dependencies from manifests, versioned

@eslint/eslintrc3.1.0 · 1×
@eslint/js9.31.0 · 1×
@koa/cors5.0.0 · 1×
@koa/ejs5.1.0 · 1×
@types/express5.0.0 · 1×
@types/express-session1.18.2 · 1×
@types/jest29.5.14 · 1×
@types/koa2.15.0 · 1×
@types/koa__ejs5.1.0 · 1×
@types/multer2.0.0 · 1×
@types/node16.18.3 · 1×
@types/serve-static1.15.8 · 1×

For agents

$ claude mcp add routing-controllers \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact