route-controller v1.3.1
Route Controller
Remark! Don't ready to use for production yet.
A Simple Express Router decorator.
Aim: To separate codes into many pieces for testing purposes.
The concept is Module contains:
Controller: Combine the controller, middleware and routingService: To connect with other service like Database.
** Alternatively: routing-controllers
Features
- Express Router decorators:
Get,Post,Put,Delete,Use,Controller - Express Middleware
Usefor Express Middleware- Support multiple middleware, e.g.
@Use(validateAuth, validateRole)(validateAuth,validateRoleis the custom middlewares)
- Basic
HttpException - Basic middleware for validating the request,
validateTypeusingclass-validator - built-in http-status-codes
Installation
Install the module
$ npm install route-controller reflect-metadataIf you want to use with TypeORM, please install
$ npm install typeorm typedi typeorm-typedi-extensionsUsage
Note: for version 1.0.0 and abovesetup the controller
// filename: users.controller.ts import { Controller, Get } from 'route-controller'; @Controller('/users') export class UsersController { @Get('/') public async getUsers(req: any, res: any, next: any) { const data:any = { name: "Micky" }; res.status(200).json({ data }); } }Setup the module
// filename: users.module.ts import { Module } from 'route-controller'; import { UsersController } from './users.controller'; @Module({ controllers: [UsersController] }) export class UserModule { }
Inject the module to Express using
useExpressServer// filename: main.ts import express from 'express'; import { UserModule } from './users.module'; app = express(); useExpressServer(app, [ UserModule ]);
The example usage with TypeORM & TypeDI
setup the entity & service
// filename: users.entity.ts import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() name: string; }The
repositorywill be injected by service oftypedi// filename: users.service.ts import { Service } from 'typedi'; import { InjectRepository } from 'typeorm-typedi-extensions'; import { User} from './users.entity'; @Service() export class UsersService { @InjectRepository(User) private repository: Repository<User>; public findAll(): Promise<User[]> { const users = this.repository.find(); return users; } }
setup the controller, (Note:
useExpressServerwill inject the service inuserServiceproperty, respectively, If you have 2 services, please make sure that the order in the providers (@Module) is setting is same order with the controller constructor. )// filename: users.controller.ts import { Controller, Get } from 'route-controller'; import { UsersService } from './users.service'; import { User} from 'users.entity'; @Controller('/users') export class UsersController { constructor(public userService: UsersService) {} @Get('/') public async getUsers(req: any, res: any, next: any) { const data: User[] = await this.userService.findAll(); res.status(200).json({ data }); } }Setup the module
// filename: users.module.ts import { Module } from 'route-controller'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; @Module({ controllers: [ UsersController ], providers: [ UsersService ] }) export class UserModule { }setup the express app & typeORM connect with the DB
// main.ts import express from 'express'; import { UserModule } from './users.module'; import { Container } from 'typedi'; import { createConnection, useContainer } from 'typeorm'; function initDatabase(){ useContainer(Container); createConnection({ // TypeORM config.... }); } async function runServer(){ // Make sure the database should be connected before inject the providers await initDatabase(); app = express(); useExpressServer(app, [ UserModule ], { // inject the container from `createConnection` container: Container; }); } runServer();
Q&A
Why we don't need to catch the error in the controller?
Answer:
addExpressControllerand the router decorator. It works becausereflect-metadatafor using save the extra the data to the function, class , method or property.If you see the code...
@Get('/') // get method and path `/` public async getUsers(req: any, res: any, next: any) { const data: User[] = await this.userService.findAllUser(); res.status(200).json({ data }); }It will be transform to
app.get('/', getUsers);but we don't handle the error yet, thanks for https://www.positronx.io/express-js-error-handling-tutorial-with-best-example/ for example of using Express error handling.
Lastly, it it will be
const asyncHelper = (fn: any) => ( function(req: Request, res: Response, next: NextFunction){ fn(req, res, next).catch(next); } ); app.get('/', asyncHelper( async (req, res, next ) => { getUsers }) );So, the
asyncHelperwill help to catch the error, and pass it to the error handling middle of Express app.Finally, the error will be passing to the error handling middle of Express app.
aap.use( (error, req, res, next ) => { res.send(error.message); })
License
MIT
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago