美文网首页
Nest.js - Helloworld & Controlle

Nest.js - Helloworld & Controlle

作者: stevekeol | 来源:发表于2020-07-08 17:34 被阅读0次

    参考文档

    介绍

    Nest.js是一款构建高效可扩展的NodeJS的框架,同时支持javascript和typescript。底层默认使用Express框架,并在之上提供了一层抽象的封装,同时暴露Express的api。

    安装

    $ npm i -g @nestjs/cli
    $ nest new project-name
    ...
    $ npm run start
    //第二步可能安装不成功:切换淘宝镜像源即可:npm config set registry https://registry.npm.taobao.org
    //启动成功后,localhost:3000可看到'hello world'
    

    Hello World项目解读

    src
    ├── app.controller.spec.ts //?
    ├── app.controller.ts //带有单个路由的基本控制器示例
    ├── app.module.ts //应用程序的根模块
    ├── app.service.ts //?
    └── main.ts //应用程序入口文件(使用 NestFactory 用来创建 Nest 应用实例)
    
    //main.ts
    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    
    async function bootstrap() {
      //create是核心类NestFactory的静态方法,用于创建应用实例;
      //create()返回一个实现了INestApplication接口的对象,并提供了一组方法。
      const app = await NestFactory.create(AppModule); 
      await app.listen(3000);
    }
    bootstrap(); //该异步函数负责引导我们的应用程序
    

    内置平台(以Express为例)

    引入@nestjs/platform-express包即可直接使用,其暴露的api是NestExpressApplication.
    当你确实要访问Express底层API时,可将该平台类型传递给NestFactory.create(),使用如下:

    import { NestExpressApplication } from '@nestjs/platform-express'
    ...
    const app = await NestFactory.create<NestExpressApplication>(AppModule);
    

    控制器

    //app.controller.ts
    import { Controller, Get } from '@nestjs/common';
    import { AppService } from './app.service';
    
    @Controller()
    export class AppController {
      constructor(private readonly appService: AppService) {}
    
      @Get()
      getHello(): string {
        return this.appService.getHello();
      }
    }
    
    • 控制器负责处理传入的 请求 和向客户端返回 响应
    • 路由机制决定哪个控制器接收哪些请求。通常每个控制器有多个路由,不同的路由可以执行不同的操作。
    • 可以使用类和装饰器,创建一个基本的控制器。
    • 装饰器将类与所需的元数据相关联,并使Nest能够创建路由映射(将请求绑定到相应的控制器)
    1. 路由
    // cats.controller.ts
    import { Controller, Get } from '@nestjs/common';
    
    @Controller('cats')
    export class CatsController {
      @Get()
      findAll(): string {
        return 'This action returns all cats';
      }
    }
    
    • 装饰器中可设置前缀;使用路由前缀('cats')可将路由分组;
    • Http请求方法装饰器(可携带路由信息)为下面的处理程序指定请求方法和路由。(GET /cats 或 GET /cats/profile等)
    • 推荐的响应写法:请求处理程序只管返回数据,其余的交给Nest。当请求处理程序返回一个js对象/数组时,nest将自动序列化为json。当返回一个基本类型(string/number/boolean)时,只发送值,不序列化。
    • 类库特有的响应写法:在函数签名通过 @Res() 注入类库特定的 响应对象(例如,Express),使用此函数,您具有使用该对象的响应处理函数。例如,使用 Express,您可以使用类似代码构建响应 response.status(200).send()。
    • 响应的状态码默认情况下始终为 200,但使用 201 的 POST请求除外。可在处理程序级别添加 @HttpCode(...) 装饰器来轻松更改此行为 。
    //使用CLI创建控制器,为项目增加对应路径下的控制器默认文件。
    //项目根目录下,nest g controller xxx. (-g: generate的缩写)
    $ nest g controller cats
    //该命令还会自动将该控制器注册在app.module.ts中的module模块里面。
    
    2. Request

    当需求访问客户端的请求细节。 可强制Nest使用@Req()装饰器将请求对象注入处理程序(不推荐)。

    //cats.controller.ts
    import { Controller, Get, Req } from '@nestjs/common'; //@Req是'请求对象注入装饰器'
    import { Request } from 'express'; //开发依赖包中已安装了@types/express,因此此处可直接使用express,并从中导出Request作为类使用
    
    @Controller('cats')
    export class CatsController {
      @Get()
      findAll(@Req() req: Request): string { 
        console.log(req);
        return 'This action returns all cats';
      }
    }
    
    • 使用专用的装饰器,而非手动从Request对象中获取诸如:查询字符串,参数,http标头,正文。
    • @Request()、@Response()、@Next()、@Session()、@Param(key?: string)、@Body(key?: string)、@Query(key?: string)、@Headers(name?: string)、@Ip()
    3. 资源

    post处理程序的写法:

    //cats.controller.ts
    import { Controller, Get, Post } from '@nestjs/common';
    
    @Controller('cats')
    export class CatsController {
      @Post()
      create(): string {
        return 'This action adds a new cat';
      }
    
      @Get()
      findAll(): string {
        return 'This action returns all cats';
      }
    }
    

    端点装饰器还有:

    • @Put()
    • @Delete()
    • @Patch()
    • @Options()
    • @Head()
    • @All()
    4. 路由通配符

    路由支持模糊匹配,如

    @Get('ab*cd')
    findAll() {
      return 'This route uses a wildcard';
    }
    
    5. 状态码

    默认情况下,响应的状态码总是200,但 POST 请求是201。更改方式如下:

    import { HttpCode } from '@nestjs/common';
    
    @Post()
    @HttpCode(204) //处理程序层添加该装饰器
    create() {
      return 'This action adds a new cat';
    }
    
    6. 响应头Headers

    需要自定义响应头Headers,使用@Header或者类库特有的响应对象(略)

    import { Header} from '@nestjs/common';
    
    @Post()
    @Header('Cache-Control', 'none')
    create() {
      return 'This action adds a new cat';
    }
    
    7. 重定向

    将响应重定向到特定url。

    @Get('docs')
    @Redirect('https://docs.nestjs.com', 302)
    getDocs(@Query('version') version) { //注意version的用法噶
      if (version && version === '5') {
        return { url: 'https://docs.nestjs.com/v5/' };
      }
    }
    
    8. 路由参数
    • 定义带参数的路由时,@Get()中可添加路由参数标记
    • 将参数装饰器添加到函数签名中,就可以获取该路由参数。
    import { Param} from '@nestjs/common';
    
    @Get(':id')
    findOne(@Param() params): string {
      console.log(params.id);
      return `This action returns a #${params.id} cat`;
    }
    
    //或
    @Get(':id')
    findOne(@Param('id') id): string {
      console.log(params.id);
      return `This action returns a #${id} cat`;
    }
    
    9. 子域路由

    当传入请求的 HTTP 主机匹配某个特定值。

    @Controller({ host: 'admin.example.com' })
    export class AdminController {
      @Get()
      index(): string {
        return 'Admin page';
      }
    }
    
    //获取主机参数
    @Controller({ host: ':account.example.com' })
    export class AccountController {
      @Get()
      getInfo(@HostParam('account') account: string) {
        return account;
      }
    
    10. Async/await ---???????????????
    //cats.controller.ts
    @Get()
    async findAll(): Promise<any[]> {
      return [];
    }
    

    Nest将自动订阅下面的源并获取最后发出的值(在流完成后):

    @Get()
    findAll(): Observable<any[]> {
      return of([]);
    }
    
    10. 请求负载

    即取出post()请求中的body。

    • 假如使用Typescript,则需要确定DTO模式数据传输对象,它定义了如何通过网络发送数
      据)。
    • 建议使用简单的类而非接口来实现DTO。因为类是ES6的一部分,编译完后仍保留在源码中,在运行时仍可引用。
    //create-cat.dto.ts
    export class CreateCatDto {
      readonly name: string;
      readonly age: number;
      readonly breed: string;
    }
    
    //cats.controller.ts
    @Post()
    async create(@Body() createCatDto: CreateCatDto) {
      //如何使用????????
      return 'This action adds a new cat';
    }
    
    • 从Post提交上来的body被命名为createCatDto,它是符合CreateCatDto类型的;
    11. 完整示例
    //cast.controller.ts
    import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
    import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';
    
    @Controller('cats')
    export class CatsController {
      @Post()
      create(@Body() createCatDto: CreateCatDto) {
        return 'This action adds a new cat';
      }
    
      @Get()
      findAll(@Query() query: ListAllEntities) {
        return `This action returns all cats (limit: ${query.limit} items)`;
      }
    
      @Get(':id')
      findOne(@Param('id') id: string) {
        return `This action returns a #${id} cat`;
      }
    
      @Put(':id')
      update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
        return `This action updates a #${id} cat`;
      }
    
      @Delete(':id')
      remove(@Param('id') id: string) {
        return `This action removes a #${id} cat`;
      }
    }
    
    12. 类库的使用方法
    • 谨慎使用类库
    • 在可能的情况下,应始终首选 Nest 标准方法
    import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
    import { Response } from 'express';
    
    @Controller('cats')
    export class CatsController {
      @Post()
      create(@Res() res: Response) {
        res.status(HttpStatus.CREATED).send();
      }
    
      @Get()
      findAll(@Res() res: Response) {
         res.status(HttpStatus.OK).json([]);
      }
    }
    

    相关文章

      网友评论

          本文标题:Nest.js - Helloworld & Controlle

          本文链接:https://www.haomeiwen.com/subject/wopqcktx.html