• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

typestack/routing-controllers: Create structured, declarative and beautifully or ...

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

typestack/routing-controllers

开源软件地址:

https://github.com/typestack/routing-controllers

开源编程语言:

TypeScript 99.9%

开源软件介绍:

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 or koa.js.

Table of Contents

Installation

  1. Install module:

    npm install routing-controllers

  2. 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-router @types/koa-bodyparser

  2. 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:

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

Example of usage

  1. Create a file UserController.ts

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

  2. Create a file app.ts

    // 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

  3. 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 that is decorated with @Body(), routing-controllers will use class-transformer to create instance of the given class type from the data received in request body. To disable this behaviour you need to specify a { classTransformer: false } in RoutingControllerOptions when creating a server.

Inject request body parameters

To inject request body parameter, use @BodyParam decorator:

@Post("/users")
saveUser(@BodyParam("name") userName: string) {
}

Inject request header parameters

To inject request header parameter, use @HeaderParam decorator:

@Post("/users")
saveUser(@HeaderParam("authorization") token: string) {
}

If you want to inject all header parameters use @HeaderParams() decorator.

Inject cookie parameters

To get a cookie parameter, use @CookieParam decorator:

@Get("/users")
getUsers(@CookieParam("username") username: string) {
}

If you want to inject all header parameters use @CookieParams() decorator.

Inject session object

To inject a session value, use @SessionParam decorator:

@Get("/login")
savePost(@SessionParam("user") user: User, @Body() post: Post) {}

If you want to inject the main session object, use @Session() without any par


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
clarkdo/hare: 发布时间:2022-06-24
下一篇:
butlermatt/dart_koans: Dart Koans. Achieve enlightenment through failure.发布时间:2022-06-24
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap