• Nest快速上手


    Nest

    官网:https://nestjs.com/
    中文网站:https://docs.nestjs.cn/
    评价: https://mp.weixin.qq.com/s/Y67O9ks-qPwVF8UqHaRY-g
    Nest 是一个渐进的 Node.js 框架,可以在 TypeScript 和 JavaScript (ES6、ES7、ES8)之上构建高效、可伸缩的企业级服务器端应用程序。
    Nest 基于 TypeScript 编写并且结合了 OOP(面向对象编程),FP(函数式编程)和 FRP (函数式响应编程)的相关理念。在设计上的很多灵感来自于 Angular,Angular 的很多模式又来自于 Java 中的 Spring 框架,依赖注入、面向切面编程等,所以我们也可以认为:Nest 是 Node.js 版的 Spring 框架。
    Nest 框架底层 HTTP 平台默认是基于 Express 实现的,所以无需担心第三方库的缺失。
    Nest 旨在成为一个与平台无关的框架。 通过平台,可以创建可重用的逻辑部件,开发人员可以利用这些部件来跨越多种不同类型的应用程序。
    从技术上讲,Nest 可以在创建适配器后使用任何 Node HTTP 框架。有两个支持开箱即用的 HTTP 平台:express 和 fastify。您可以选择最适合您需求的产品。
    NestJs 的核心思想:就是提供了一个层与层直接的耦合度极小,抽象化极高的一个架构体系。

    建立项目

    //安装Nest CLI
    npm i -g @nestjs/cli .
    
    //使用Nest CLI 创建项目
    nest new project-name
    
    // 运行项目
    npm run start
    

    src目录核心文件

    app.controller.ts 带有单个路由的基本控制器示例。
    app.module.ts 应用程序的根模块。
    main.ts 应用程序入口文件。它使用 NestFactory 用来创建 Nest 应用实例。

    NEST命令行工具

    nest --help
    

    可以列出命令行的主要命令以及帮助

    创建

    • new(简写n)[options] [name] :创建一个NEST应用,例如 nest n hello-world。选项中支持:
      • --directory 指定目标目录
      • -d或--dry-run  不输出创建过程中的报告
      • -g或--skip-git  不要初始化git仓库(默认是会在项目创建git仓库)
      • -s或--skip-install 不要安装依赖哭
      • -p或--package-manager [name] 指定包管理工具
      • -l或--language [lang] 指定语言JS或者TS
      • -c或--collection [name] 用特定的架构生成项目

    构建

    • build [options] [app] : 构建项目,默认会将TS文件构建到项目的dist目录中;options有:
      • -c或--config [path] 用cli构建时特定的配置文件
      • -p或--path [path] tsconfig配置文件
      • -w或--watch 实时重加载,观察模式
      • --watchAssets 观察非ts文件模式
      • --webpackPath [path] webpack的配置文件
      • --tsc 使用tsc编译

    运行

    • start [options] [app]:运行NEST项目,options有:
      • -c或--config [path] 用cli构建时特定的配置文件
      • -p或--path [path] tsconfig配置文件
      • -w或--watch 实时重加载,观察模式
      • --watchAssets 观察非ts文件模式
      • -d或--debug [hostport] 调试模式
      • --webpack用webpack编译
      • --webpackPath [path] webpack的配置文件
      • --tsc 使用tsc编译
      • -e或--exec [binary] 以二进制运行(默认用node)
      • --preserveWatchOutput tsc的观察模式

    更新

    • update或u [options]:更新当前项目的依赖组件
      • -f或--force 强制重新安装依赖
      • -t或--tag 升级被打上(latest | beta | rc | next tag)的组件

    Nest架构元素

    其类型如下表:

    名称 别名 说明
    application application 在工作区中创建一个新的应用
    class cl 新的类
    configuration config 命令行的配置文件
    controller co 控制器
    decorator d 自定义装饰器
    filter f 过滤器
    gateway ga 请求的网关
    guard gu 守卫
    interceptor in 拦截器
    interface interface 接口
    middleware mi 中间件
    module mo 模块
    pipe pi 管道
    provider pr 功能组
    resolver r GraphQL处理器
    service s 服务
    library lib 单独库模式下创建一个库
    sub-app app 子应用
    resource res 一个数据模型的CRUD

    平台

    Nest 旨在成为一个与平台无关的框架。 通过平台,可以创建可重用的逻辑部件,开发人员可以利用这些部件来跨越多种不同类型的应用程序

    有两个支持开箱即用的 HTTP 平台:expressfastify
    暴露自己的 API分别是 NestExpressApplication 和 NestFastifyApplication

    const app = await NestFactory.create<NestExpressApplication>(AppModule);
    

    控制器

    控制器负责处理传入的 请求 和向客户端返回 响应
    创建一个基本的控制器:类和装饰器
    CLI 创建控制器

    $ nest g controller cats
    

    路由

    Nestjs 中没有单独配置路由的地方。定义好控制器后 nestjs 会自动给我们配置对应的路由

      //中控制器内直接用装饰器匹配路由
      @Get()
      index() {
        //输出内容
        return '我是article控制器get请求';
      }
    

    两种不同的操作响应:** 标准(推荐)和 类库**

    关于 nest 的 return: 当请求处理程序返回 JavaScript 对象或数组时,它将自动序列化为JSON。但是,当它返回一个字符串时,Nest 将只发送一个字符串而不是序列化它。这使响应处理变得简单:只需要返回值,Nest 负责其余部分。

    类库响应方式

    通过 @Res() 注入类库特定的 响应对象

    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 标准响应处理的 Nest 功能的兼容性,例如拦截器和 @HttpCode() 装饰器。此外,您的代码可能变得依赖于平台(因为底层库可能在响应对象上有不同的 API),并且更难测试(您必须模拟响应对象等)。因此,在可能的情况下,应始终首选 Nest 标准方法

    装饰器

    装饰器将类与所需的元数据相关联,并使 Nest 能够创建路由映射

    请求装饰器

    Nestjs也提供了其他HTTP请求方法的装饰器 @Put() 、@Delete()、@Patch()、 @Options()、 @Head()和 @All()
    用法都差不多

    import { Controller, Get } from '@nestjs/common';
    
    @Controller('cats')
    export class CatsController {
      @Get()
      findAll(): string {
        return 'This action returns all cats';
      }
    }
    
    

    获取Get 传值或者Post 提交的数据

    @Request() req
    @Response() res
    @Next() next
    @Session() req.session
    @Param(key?: string) req.params / req.params[key]
    @Body(key?: string) req.body / req.body[key]
    @Query(key?: string) req.query / req.query[key]
    @Headers(name?: string) req.headers / req.headers[name]
    import {Body, Controller, Get, Post, Query, Request} from '@nestjs/common';
    
    @Controller('article')
    export class ArticleController {
      //get请求
      @Get()
      index() {
        //输出内容
        return '我是article控制器';
      }
    
      //路由拼接article/add
      @Get('add')
      //获取url装饰器(get参数)
      addArticle(@Query() query) {
        console.log(query)
        //输出内容
        return '我是article/add';
      }
    
      @Get('edit')
      //request装饰器获取请求信息
      editArticle(@Request() req){
        console.log(req.query)
        return "我是article/edit"
      }
    
      @Post('create')
      //Body装饰器获取post内容
      create(@Body() body){
        console.log(body)
        return '我是Post请求'
      }
      
    }
    

    状态码

    @HttpCode

    @Post()
    @HttpCode(204)
    create() {
      return 'This action adds a new cat';
    }
    

    重定向

    @Redirect()

    @Get()
    @Redirect('https://nestjs.com', 301)
    

    子域路由

    @Controller 装饰器可以接受一个 host 选项,以要求传入请求的 HTTP 主机匹配某个特定值

    @Controller({ host: 'admin.example.com' })
    export class AdminController {
      @Get()
      index(): string {
        return 'Admin page';
      }
    }
    
    

    动态路由

    不常用
    注意动态路由要放在下面,不然会先匹配,下面路由匹配不成功

    import {Controller, Get, Param, Query} from '@nestjs/common';
    
    @Controller('news')
    export class NewsController {
    
      @Get()
      addDate(@Query('id') id){
        console.log(id)
        return "获取里面参数"
      }
    
      //news/123
      @Get(":id")
      index(@Param() param){
        //{id: '123'}
        console.log(param)
        return "我是动态路由"
      }
    }
    

    请求负载

    使用 TypeScript, POST接受客户端参数,需要确定 DTO(数据传输对象)模式
    DTO是一个对象,它定义了如何通过网络发送数据,通过使用 TypeScript接口或简单的类实现(推荐使用类)

    区别:类是JavaScript ES6标准的一部分,因此它们在编译后的 JavaScript中保留为实际实体。另一方面,由于 TypeScript接口在转换过程中被删除

    创建 CreateCatDto 类

    create-cat.dto.ts

    export class CreateCatDto {
      readonly name: string;
      readonly age: number;
      readonly breed: string;
    }
    

    它只有三个基本属性。 之后,我们可以在 CatsController中使用新创建的DTO

    cats.controller.ts

    @Post()
    async create(@Body() createCatDto: CreateCatDto) {
      return 'This action adds a new cat';
    }
    

    完整示例

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

    最后一步

    控制器已经准备就绪,但是 Nest 不知道 CatsController 是否存在

    app.module.ts

    import { Module } from '@nestjs/common';
    import { CatsController } from './cats/cats.controller';
    
    @Module({
      controllers: [CatsController],
    })
    export class AppModule {}
    

    使用 @Module()装饰器将元数据附加到模块类,Nest 现在可以轻松反映必须安装的控制器

    配置静态资源

    nest若要加载静态资源则需要配置静态资源目录
    入口文件src/main

    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    //入口文件引入express平台HTTP平台
    import { NestExpressApplication } from '@nestjs/platform-express'
    //引入path模块的join方法
    import {join} from "path";
    
    async function bootstrap() {
      const app = await NestFactory.create<NestExpressApplication>(AppModule);
      // app.useStaticAssets('public');  //配置静态资源目录
      app.useStaticAssets(join(__dirname, '..', 'public'), {   //配置虚拟目录
        prefix: '/static/', //设置虚拟路径
      });
      await app.listen(3000);
    }
    bootstrap();
    
  • 相关阅读:
    java实现httpclient 访问
    推荐博文
    Running With xpi
    1 Spring MVC 原理
    windows服务相关
    求职面试三部曲
    使用mvn插件执行工程单元测试OOM的解决办法
    maven-surefire插件问题
    小问题
    NFA到DFA实例
  • 原文地址:https://www.cnblogs.com/zzghk/p/15225775.html
Copyright © 2020-2023  润新知