# Learning NestJS, Part1 ###### tags: `Nestjs` ## Learning The Basics ### 套件組成 - Nestjs/common: NestJS中會用到的functions, classes等等 - Nestjs/platform-express: 使NestJS可使用ExpressJS來處理HTTP請求 - Reflect-Metadata: 幫助使用decorators - Typescript: 使用Typescript來編寫Nest Apps ### 快速建立App 1. 安裝套件 2. 設定Typescript Config 3. 建立Nest的Module及Controller 4. 啟動App ### NestJS Tools - Pipe: 驗證Request的資料 - Guard: 確認使用者是否經過驗證 - Controller: 將請求導向某個特定的Function - Service: 處理商業邏輯的部分 - Repository: 存取資料庫 ### 命名慣例 - main.ts內為啟動程式的function bootstrap - 一個class一個file - class AppController ==> app.controller.ts - class AppModule ==> app.module.ts Routing規則: ``` @Controller('/app') export class AppController { @Get('/hi') getRootRoute() { return 'Hi, there!'; } @Get('/bye') getRootRoute() { return 'Bye, there!'; } } ``` 當連線為http://localhost:3000/app/hi 則會跳出"Hi, there!"的字串 當連線為http://localhost:3000/app/bye 則會跳出"Bye, there!"的字串 --- ## 使用Nest Cli建立Project ### 指令流程 1. 使用npm指令安裝: `npm i -g @nestjs/cli` 2. 使用cli指令快速建立project: `nest new "App Name"` 3. 使用package.json內的script啟動server並於程式碼改動時自動重啟: `npm run start:dev` 4. 使用指令產生module:`nest generate module messages` Create src/messages/messages.module.ts 5. 使用指令產生controller:`nest generate controller messages/messages --flat` CREATE src/messages/messages.controller.ts CREATE src/messages/messages.controller.spec.ts UPDATE src/messages/messages.module.ts <= 自動更新messages.module.ts ``` nest generate controller <= Type of class to generate messages <= Where the files in /messages <= Call the class 'messages' --flat <= Don't create an extra folder called 'controllers' ``` --- ## 使用Decorators ### Request Object對照表 | Decorator | Request Object | | ---------------------- | ------------------------------ | | @Request() | @Req() req | | @Response() | @Res()* 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]| | @Ip() | req.ip | | @HostParam() | req.hosts | ### Example **1. @body** ``` @Post() createMessage(@Body() body:any) { console.log(body); } ``` POST http://localhost:3000/messages Content-Type: application/json ``` { "content": "Hello World" } ``` 於終端機可看見回傳 **Hello World** **2. @Param** ``` @Get('/:id') getMessage(@Param('id') id: string) { console.log(id); } ``` 於終端機可看見回傳 **1** --- ## 使用Pipe驗證資料 流程: 1. 設定Global驗證 ``` // main.ts import { ValidationPipe } from '@nestjs/common'; ... async function bootstrap() { ... app.useGlobalPipes(new ValidationPipe()); ... } ``` 2. 在messages資料夾下建立名為dtos的資料夾,**DTO為Data Transfer Object** 3. 在dtos建立檔案create-messages.dto.ts,在此檔案中規範req.body中須包含的資料型態 並安裝class-validator及class-transformer的套件。 ``` // create-messages.dto.ts import { IsString, Length } from 'class-validator'; export class CreateMessageDto { @IsString() @Length(4, 20) readonly content: string; } ``` 4. 在messages.controller.ts中加入驗證 ``` // messages.controller.ts import { CreateMessageDto } from './dtos/create-message.dto'; ... export class MessagesController { ... @Post() createMessage(@Body() body: CreateMessageDto) { console.log(body); } ... } ``` 5. 若req.body的content內容不是字串及長度不對時跳出的錯誤訊息為下: ``` { "statusCode": 400, "message": [ "content must be longer than or equal to 4 and shorter than or equal to 20 characters", "content must be a string" ], "error": "Bad Request" } ``` ### Behind The Pipe Request POST /messags => DTO => Route Handler {"content": "Hi there"} - [class-transformer](https://github.com/typestack/class-transformer#what-is-class-transformer) 將 plain objects 轉為 class objects - [class-validator library](https://github.com/typestack/class-validator#validation-decorators) class-validator在TS轉譯成plain JS後,依照正常狀態會消失 ``` @Post() createMessage(@Body() body: CreateMessageDto) { ^^^^^^^^^^^^^^^^ console.log(body); } ``` 在tsconfig.ts中設定 "emitDecoratorMetadata": true 即可在轉譯後保留
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up