nestjs快速上手指南

Nestjs是一個基於Nodejs的服務器框架,吸收和借鑑了前端框架Angular的風格,完全支持TypeScript語言,因此,對於熟悉Angular以及TypeScript的用戶來說,是服務器端編程的不二選擇。在底層,Nestjs支持流行的Express(默認)框架,但也可以選擇Fastify框架進行開發。


nestjs快速上手指南


1.Nestjs安裝與快速啟動


1.1 nestjs安裝


Nestjs項目可以通過命令行,git或者手動創建三種方法開始。一般來說,更推薦使用命令行指令進行開發。使用命令行指令時,需要先安裝nestjs-cli命令行模塊。按照下述指令開始一個新的項目。


<code>#npm
npm i -g @nestjs/cli
nest new project-name
#yarn
yarn global add @nestjs/cli/<code>


使用git安裝時,可通過以下命令從github上覆制示例項目並在此基礎上開始新項目


<code>git clone https://github.com/nestjs/typescript-starter.git project/<code>


對於高級用戶來說,可能僅需要使用一部分nestjs的核心功能,在這種情況下,通過下列指令可以在項目中安裝需要的模塊並手動開始一個項目。


<code>$ npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata/<code>


nestjs快速上手指南


1.2 腳手架及項目啟動


安裝完nestjs的命令行工具後,可通過下列命令快速搭建項目腳手架以開始新項目


<code>nest new project-name
cd project-name
npm run start
#也可以以開發模式啟動項目,這樣項目中任何修改和變化都可以實時編譯
#在腳手架項目的package.json文件中可以看到更多的啟動項目及測試的腳本命令
#npm run start:dev/<code>


通過git命令下載的項目,只要進入項目,並按照常規的nodejs項目安裝模塊並啟動即可


<code>cd project
npm install
npm run start/<code>


運行上述命令後,打開http://localhost:3000,可以看到hello world頁面。


1.3 Visual Studio Code配置Nestjs項目插件


在VS Code中進行Nestjs項目開發時,除了node環境和上述nestjs命令行工具外,可以安裝以下插件來提高項目開發效率和速度。


  • nestjs Files,該插件可以實現nestjs部分生成命令的右鍵快捷操作。例如,如果要在一個名為cats的文件夾下新建Controller,可以在cats文件夾上點擊右鍵,選擇Generate Controller並輸入Controller名稱cats,就可以生成cats.controller.ts文件並在其中生成並導出CatsController類。這和Angular插件的用法非常相似,實際上相當於執行nest g controller cats或者nest g service cats命令。
  • NestJs Snippets,提供了大量的nestjs語法片段可快速使用。在命令欄Ctrl+Shift+P輸入n-可以看到插件支持的大部分語法和命令。
  • REST Client。用於測試API的非常高效的VS Code插件,基本可以完全取代Postman。


2. nestjs腳手架項目


nestjs快速上手指南


除了主入口文件main.ts外,nestjs項目一般模塊化組成。默認的腳手架項目包括了app.module.ts,app.controller.ts,app.service.ts幾個文件。和angular項目結構類似,在nestjs項目中,controller作為控制器,一般用於處理請求並返回響應,service用來實現後臺邏輯。


在controller中,使用裝飾器來區分不同的路徑和請求。在腳手架項目中,controller默認路徑的get方法返回appService.getHello()方法,appService.getHello()方法,後者返回一個Hello World字符串。在實際項目中,這樣使用同步方法來返回的情況非常少見,更多的時候都是使用異步的方法返回用戶請求。以下對默認腳手架項目做一些修改,以異步的方式返回用戶請求。默認腳手架項目返回如下內容:


<code>//Controller
@Get()
getHello(): string {
return this.appService.getHello();}
//Service
getHello(): string {
return 'Hello World!';
}/<code>


在app.controller.ts文件中分別做如下修改:


<code>//Controller
import { Observable,of } from 'rxjs';
getHello():Observable<string>{
return of(this.appService.getHello());
}/<string>/<code>


這裡使用到了異步編程中最常用的rxjs模塊中Observable和of,將字符串Hello World轉換為異步對象,並返回到controller中通過async標識的異步函數中再響應給用戶。雖然看到的同樣是Hello World字符串,但在處理更復雜任務的時候,異步編程的優勢就可以更好地顯現出來。


3.通過nestjs響應網絡請求


3.1 網絡請求裝飾器


nestjs可以通過裝飾器響應不同類型的網絡請求。nestjs默認啟用express框架,系統提供的裝飾器可以滿足大部分網絡請求,但也支持自定義裝飾器來實現更多功能。常用的裝飾器與express的對應關係列表如下:

裝飾器請求@Request()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]@HttpStatus 自定義http狀態


3.2 nestjs支持的一些http請求和方法:


  • nestjs支持@Put() 、 @Delete()、 @Patch()、 @Options()、 @Head()和 @All()裝飾器以這些表示各自的 HTTP請求方法
  • 支持通過@HttpCode()裝飾器來返回指定的狀態碼如201、404等(如@HttpCode(201)),需要從@nestjs/common導入。
  • 支持@Header裝飾器來相應特定的header請求如@Header('Cache-Control', 'none'),同樣需要從@nestjs/common導入。
  • 支持@Redirect裝飾器來重定向資源例如@Redirect(http://www.weizhiyong.com`,301)。
  • 支持模式匹配通配符,例如星號(*)可以被匹配任何字符組合


3.3 路由參數


nestjs可以使用裝飾器取得路由參數或http請求中的內容,一般來說,@Param參數用來讀取路由參數,如https://www.weizhiyong.com/archives/:id格式的路由,在讀取id參數時可以採用以下兩種方式:


<code>@Controller('archives')
@Get(':id')
getId(@Param() params):string{
let result=params.id;
return result;
}
//或者
@Controller('archives')
@Get(':id')
getId(@Param('id')id):string{
return id;
}/<code>


類似地,如果要從JSON格式的Body請求中取得參數,也可以使用諸如@Body()reqbody 之類的參數進行獲取。

在Controller中,也可以通過host參數添加特定的域名來訪問指定值(僅適用於Express),例如.Controller({ host: 'admin.example.com' })。


4.nestjs入門示例


nestjs快速上手指南


在腳手架項目的基礎上,參考官方文檔,新建一個cats模塊,來實現對cat的添加和基本查找功能。

在項目根目錄下新建cats目錄,並在其中新建cats.service.ts,cats.controller.ts和cats.module.ts文件(可以通過前節的nestjs File完成),為了實現數據接口,還需要在cats文件夾下新建dto/create-cat.dto.ts文件和interfaces/cat.interface.ts文件。


4.1 cat.interface.ts接口文件


該文件導出一個cat的接口,用於實現不同文件之間的數據交互。在實際項目中,接口文件不僅僅用於項目中不同模塊之間的數據交互,也為實現前後端的統一開發提供了條件。


<code>export interface Cat{
name:string;
age:number;
breed:string;
}/<code>


4.2 create-cat.dto.ts數據傳輸對象(DTO)文件


在處理數據時,通常使用dto來針對不同操作指定數據接口,和interface不同,dto往往用類的方式進行聲明。本文件的內容如下:


<code>export class CreateCatDto{
readonly name:string;
readonly age:number;
readonly breed:string;

}/<code>


4.3 cats.service.ts 服務器文件


服務在nestjs中被稱為提供者(provider),與angular類似,provider通過注入的方式注入在controller或者module文件中以創建各種關係並執行不同功能,除了service外,其他被稱為provider的類型還包括repository,factory和helper,所有的provider在nestjs中都通過@Injectable()裝飾器來標識。除了@Injectable()裝飾器外,提供者還支持@Optional()裝飾器,來表示該provider是可選的。除了諸如某個類之外,提供者也可僅針對類中的某個屬性進行諸如。本示例的文件內容如下:


<code>import { Injectable } from '@nestjs/common';
import {Cat} from './interfaces/cat.interface';

@Injectable()
export class CatsService {
private readonly cats:Cat[]=[];
create(cat:Cat){
this.cats.push(cat);
return {'status':'ok'};
}
findAll():Cat[]{
return this.cats;
}
}/<code>


4.4 cats.controller.ts 控制器文件


控制器通過@Controller('cats')裝飾器標識路徑cats。通過@Post,@Get等裝飾器來實現不同的http請求方法。這裡使用了異步函數的實現方式,這也是nestjs中主要使用的方式。需要注意的是,異步函數可以通過Promise或者Observable兩種不同方法來實現。當使用Promise時,需要用async前綴,需要Observable時,需要從rxjs中引入Observable和of。在本例中,通過@Body() createCatDto:CreateCatDto裝飾器與數據傳輸對象從用戶請求中讀取數據,並保證數據格式符合要求。


<code>import { Controller,Get,Post,Body } from '@nestjs/common';
import {CatsService} from './cats.service';
import {Cat} from './interfaces/cat.interface';
import {CreateCatDto} from './dto/create-cat.dto';
import {Observable,of} from 'rxjs';

@Controller('cats')
export class CatsController {
constructor(private readonly catsService:CatsService){}

@Post()
create(@Body() createCatDto:CreateCatDto):Observable{
return of(this.catsService.create(createCatDto));
}

@Get()
findAll():Observable{
return of(this.catsService.findAll());
}
// async findAll():Promise{
// return this.catsService.findAll();
// }
}
/<code>


4.5 cats.module.ts模塊文件


模塊文件內容如下,在模塊文件中列出了本模塊下的Controller和Service,如果需要引入其他模塊和內容,也需要在imports中列出。如果要在模塊間共享服務或者實例,也可以通過exports數組列出,例如要在其他模塊中使用CatsService,可參見下文(註釋掉)的exports部分代碼。如果要在模塊中注入提供者(比如出於配置參數的目的),也可以在模塊的constructor中實現(見下列代碼中註釋部分)。

在nestjs中,全局模塊通過@Global()裝飾器標識,動態模塊可以使用forRoot來同步或異步(使用Promise)返回。


<code>import { CatsService } from './cats.service';
import { CatsController } from './cats.controller';
import { Module } from '@nestjs/common';

@Module({
imports: [],
controllers: [
CatsController, ],
providers: [
CatsService, ],
//exports:[CatsService]
})
export class CatsModule {
//constructor(private readonly someService:SomeService){}

}/<code>


最後,修改app.module.ts文件以導入並使用cats模塊。


<code>import { CatsModule } from './cats/cats.module';
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
imports: [
CatsModule, ],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}/<code>


4.6 使用REST Client客戶端測試


編寫一個後綴為.http的文件,就可以在nest項目運行時通過REST Client插件進行測試。在REST Client中,@用於標識變量,如以下示例中的 host 變量。 ### 用來隔開不同的命令,以保證每次執行指定的變量。可以在指令行點擊指令上方的send request或者使用快捷鍵Ctrl+Alt+R來發送指令,並驗證返回情況。


<code>@host=http://127.0.0.1:3000

###
{{host}}

###
Get {{host}}/cats
content-type: application/json

###
Post {{host}}/cats
content-type: application/json

{
"name":"Kitten1",
"age":1
}

###
Post {{host}}/cats
content-type: application/json

{
"name":"Kitten2",
"age":2
}/<code>


nestjs資源


  • nestjs英文文檔
  • nestjs中文文檔
  • 相關資料
    -typeorm倉庫
    -Jest測試框架中文文檔
    -github nest學習資源


分享到:


相關文章: