# 简介
Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架,提供了一个开箱即用的应用程序体系结构 (opens new window)。
# 安装与运行
# 1. 前置
- node
 - npm包管理工具
 
npm i -g @nestjs/cli
nest new project-name
npm run start
# 2. 启动效果

入口/get

# 起步使用
# 1. 项目结构

- main.ts:应用程序入口,使用核心函数 NestFactory 来创建 Nest 应用程序的实例。
 - app.service.ts:service层,具有单一方法的基本服务(service)method
 - app.controller.ts:controller层,带有单个路由的基本控制器
 - app.model.ts:model层,T应用程序的根模块(root module)
 - app.controller.spec.ts:单元测试层
 
# 2. 分层分析 - main.ts

- 定义了异步函数bootstrap,引导应用程序的启动过程
 - 使用了 NestFactory 核心类创建了一个 Nest 应用程序的实例
 - NestFactory 暴露了一些静态方法用于创建应用程序的实例。其中,create() 方法返回一个应用程序的对象
 - app实例监听3000端口
 
# 3. 分层分析 - app.service.ts

- 定义了一个函数getHello()并导出为AppService
 - 使用@Injectable (opens new window)(can be managed by the Nest IoC container)装饰器装饰Appservice
 
# 4. 分层分析 - app.controller.ts

- 消费了AppServie,返回值为AppServie中getHello()的返回值
 - 定义了一个函数并导出为AppController
 - 使用@Controller (opens new window)(allows us to easily group a set of related routes, and minimize repetitive code.)装饰器装饰AppController
 - 使用@get (opens new window)(tells Nest to create a handler for a specific endpoint for HTTP requests. )装饰器装饰函数getHello,这里可以自己规定请求入口
 
# 5. 分层分析 - app.model.ts

创建一个AppModel关联service和controller,使用@Modal装饰器装饰,此model即为根model,在入口文件处导入即可。
- A feature module simply organizes code relevant for a specific feature, keeping code organized and establishing clear boundaries
 - Each application has at least one module, a root module.
 - The @Module() decorator takes a single object describe the module.
 - The last thing we need to do is import this module into the root module (the AppModule, defined in the app.module.ts file).
 
# 6. 分层分析 - dto(自建)
数据验证(格式、非空),安装class-validator
npm i --save class-validator class-transformer
......
# 简介
Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架,提供了一个开箱即用的应用程序体系结构 (opens new window)。
# 前置
# 模块导航
- 1.Modules --OK
 - 2.Controllers								--OK
- nest-swagger --OK
 
 - 3.Providers --writing...
 - 4.Middleware --OK
 - 5.Pipes --learning...
 
# 1. Modules
a class annotated with a @Module() decorator The @Module() decorator provides metadata that Nest makes use of to organize the application structure.
Modules,即组织层,职责是组织相关模块

@Module()装饰器接受一个对象,其属性描述了该模块,属性分别是:
- providers 提供商,提供了service服务
 - controllers 控制器,提供了控制器集合
 - imports 依赖注入
 - exports 模块导出
 
# 2. Controllers
Controllers are responsible for handling incoming requests and returning responses to the client. Frequently, each controller has more than one route, and different routes can perform different actions.

Controllers,即控制层,职责是接收客户端请求并发送结果给对方。
- Routing 在@Controller()指定路由前缀,@Get()指定方法入口
 
import { Controller, Get } from '@nestjs/common';
@Controller('/hello')
export class CatsController {
  @Get('/get')
  getHello() {
    return 'hello';
  }
}
- Request object @Req()装饰器,指示Nest注入请求对象,从而访问请求对象。
 
import { Controller, Bind, Get, Req } from '@nestjs/common';
@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
- Resources @Post()创建新资源
 
import { Controller, Post } from '@nestjs/common';
@Controller('/hello')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }
}
- Route wildcards 字符?、+、*和()可以在路由路径中使用,它们是正则表达式对应的子集,匹配符合规则的路由。
 
@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}
- Status code @HttpCode()设定响应状态码
 
@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
- Header @Header()自定义响应头
 
@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}
- Redirection @Redirect()请求重定向
 
@Get()
@Redirect('https://nestjs.com', 301)
- Route parameters @Param()接收URL中的参数
 
@Get(':id')
@Bind(Param())
findOne(params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
Express写法
@Get(':id')
findOne(@Param() params): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
通过名称直接引用路由参数
@@filename()
@Get(':id')
findOne(@Param('id') id: string): string {
  return `This action returns a #${id} cat`;
}
@@switch
@Get(':id')
@Bind(Param('id'))
findOne(id) {
  return `This action returns a #${id} cat`;
}
- Sub-Domain Routing @Controller装饰器可以采用一个主机选项来要求传入请求的HTTP主机匹配某个特定的值。
 
@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}
- Scopes
 
...
- Asynchronicity 支持异步,返回p、Promise()
 
@Get()
async findAll(): Promise<any[]> {
  return [];
}
@Get()
async findAll() {
  return [];
}
- Request payloads @Body()接收post请求参数,需先创建DTO
 
export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
- Handling errors 错误处理 (opens new window)
 
# nest-swagger
安装nest-swagger (opens new window)
  npm install --save @nestjs/swagger swagger-ui-express
引入swagger包
  import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
进行信息项配置
  // swagger配置
  const swaggerOptions = new DocumentBuilder()
    .setTitle('nest-swagger') 
    .setDescription('zxy-learning')
    .setVersion('1.0')
    .addBasicAuth()
    .build();
  const document = SwaggerModule.createDocument(app, swaggerOptions);
  SwaggerModule.setup('doc', app, document);

# 3. Providers
Many of the basic Nest classes may be treated as a provider – services, repositories, factories, helpers, and so on. It can inject dependencies.

Providers即提供者,可以注入依赖项,服务、存储库、工厂、帮助程序等都可以被视为提供者。如控制器Controllers应该处理HTTP请求,并将更复杂的任务委托给提供者。
- Services
 
# 4. Middleware
a function which is called before the route handler.
中间件,在请求前使用中间件进行相关处理

- 实现自NestMiddleware
 
import { NestMiddleware } from '@nestjs/common';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}
- Applying middleware
 
全局注册LoggerMiddleware,全局匹配路由cats
const app = await NestFactory.create(AppModule);
app.use(logger);
局部注册helloMiddleware
import { Module, RequestMethod } from '@nestjs/common';
import { helloMiddleware } from './common/middleware/hello.middleware';
export class helloModule {
  configure(consumer) {
    consumer
      .apply(helloMiddleware)
      .forRoutes('cats');
  }
}
- Route wildcards
 
支持基于模式的路由。字符?、+、*和()可以在路由路径中使用,它们是正则表达式对应的子集,匹配符合规则的路由。
forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
- Excluding routes
 
exclude()方法排除某些路由以避免使用中间件
consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST }
  )
  .forRoutes(CatsController);
# 5. Pipes
......