Nestjs是一個基於Nodejs的伺服器框架,吸收和借鑑了前端框架Angular的風格,完全支援TypeScript語言,因此,對於熟悉Angular以及TypeScript的使用者來說,是伺服器端程式設計的不二選擇。在底層,Nestjs支援流行的Express(預設)框架,但也可以選擇Fastify框架進行開發。
1.Nestjs安裝與快速啟動1.1 nestjs安裝Nestjs專案可以通過命令列,git或者手動建立三種方法開始。一般來說,更推薦使用命令列指令進行開發。使用命令列指令時,需要先安裝nestjs-cli命令列模組。按照下述指令開始一個新的專案。
#npmnpm i -g @nestjs/clinest new project-name#yarnyarn global add @nestjs/cli
使用git安裝時,可通過以下命令從github上覆制示例專案並在此基礎上開始新專案
git clone /file/2020/04/01/20200401073343_3389.jpg project
對於高階使用者來說,可能僅需要使用一部分nestjs的核心功能,在這種情況下,通過下列指令可以在專案中安裝需要的模組並手動開始一個專案。
$ npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata
1.2 腳手架及專案啟動
安裝完nestjs的命令列工具後,可通過下列命令快速搭建專案腳手架以開始新專案
nest new project-namecd project-namenpm run start#也可以以開發模式啟動專案,這樣專案中任何修改和變化都可以實時編譯#在腳手架專案的package.json檔案中可以看到更多的啟動專案及測試的指令碼命令#npm run start:dev
通過git命令下載的專案,只要進入專案,並按照常規的nodejs專案安裝模組並啟動即可
cd projectnpm installnpm run start
執行上述命令後,開啟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腳手架專案除了主入口檔案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字串。在實際專案中,這樣使用同步方法來返回的情況非常少見,更多的時候都是使用非同步的方法返回使用者請求。以下對預設腳手架專案做一些修改,以非同步的方式返回使用者請求。預設腳手架專案返回如下內容:
//Controller@Get() getHello(): string { return this.appService.getHello();}//Service getHello(): string { return 'Hello World!'; }
在app.controller.ts檔案中分別做如下修改:
//Controllerimport { Observable,of } from 'rxjs';getHello():Observable<string>{ return of(this.appService.getHello()); }
這裡使用到了非同步程式設計中最常用的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引數時可以採用以下兩種方式:
@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;}
類似地,如果要從JSON格式的Body請求中取得引數,也可以使用諸如@Body()reqbody 之類的引數進行獲取。
在Controller中,也可以通過host引數新增特定的域名來訪問指定值(僅適用於Express),例如.Controller({ host: 'admin.example.com' })。
4.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的介面,用於實現不同檔案之間的資料互動。在實際專案中,介面檔案不僅僅用於專案中不同模組之間的資料互動,也為實現前後端的統一開發提供了條件。
export interface Cat{ name:string; age:number; breed:string;}
4.2 create-cat.dto.ts資料傳輸物件(DTO)檔案
在處理資料時,通常使用dto來針對不同操作指定資料介面,和interface不同,dto往往用類的方式進行宣告。本檔案的內容如下:
export class CreateCatDto{ readonly name:string; readonly age:number; readonly breed:string;}
4.3 cats.service.ts 伺服器檔案
服務在nestjs中被稱為提供者(provider),與angular類似,provider通過注入的方式注入在controller或者module檔案中以建立各種關係並執行不同功能,除了service外,其他被稱為provider的型別還包括repository,factory和helper,所有的provider在nestjs中都通過@Injectable()裝飾器來標識。除了@Injectable()裝飾器外,提供者還支援@Optional()裝飾器,來表示該provider是可選的。除了諸如某個類之外,提供者也可僅針對類中的某個屬性進行諸如。本示例的檔案內容如下:
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; }}
4.4 cats.controller.ts 控制器檔案
控制器通過@Controller('cats')裝飾器標識路徑cats。通過@Post,@Get等裝飾器來實現不同的http請求方法。這裡使用了非同步函式的實現方式,這也是nestjs中主要使用的方式。需要注意的是,非同步函式可以通過Promise或者Observable兩種不同方法來實現。當使用Promise時,需要用async字首,需要Observable時,需要從rxjs中引入Observable和of。在本例中,通過@Body() createCatDto:CreateCatDto裝飾器與資料傳輸物件從使用者請求中讀取資料,並保證資料格式符合要求。
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<any>{ return of(this.catsService.create(createCatDto)); } @Get() findAll():Observable<Cat[]>{ return of(this.catsService.findAll()); } // async findAll():Promise<Cat[]>{ // return this.catsService.findAll(); // }}
4.5 cats.module.ts模組檔案模組檔案內容如下,在模組檔案中列出了本模組下的Controller和Service,如果需要引入其他模組和內容,也需要在imports中列出。如果要在模組間共享服務或者例項,也可以通過exports陣列列出,例如要在其他模組中使用CatsService,可參見下文(註釋掉)的exports部分程式碼。如果要在模組中注入提供者(比如出於配置引數的目的),也可以在模組的constructor中實現(見下列程式碼中註釋部分)。
在nestjs中,全域性模組通過@Global()裝飾器標識,動態模組可以使用forRoot來同步或非同步(使用Promise)返回。
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){}}
最後,修改app.module.ts檔案以匯入並使用cats模組。
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 {}
4.6 使用REST Client客戶端測試
編寫一個字尾為.http的檔案,就可以在nest專案執行時通過REST Client外掛進行測試。在REST Client中,@用於標識變數,如以下示例中的 host 變數。 ### 用來隔開不同的命令,以保證每次執行指定的變數。可以在指令行點選指令上方的send request或者使用快捷鍵Ctrl+Alt+R來發送指令,並驗證返回情況。
@host=http://127.0.0.1:3000###{{host}}###Get {{host}}/catscontent-type: application/json###Post {{host}}/catscontent-type: application/json{ "name":"Kitten1", "age":1}###Post {{host}}/catscontent-type: application/json{ "name":"Kitten2", "age":2}
nestjs資源nestjs英文文件nestjs中文文件相關資料-typeorm倉庫-Jest測試框架中文文件-github nest學習資源