Nest (NestJS)是一個用於構建高效、可伸縮的 Node.js 服務器端框架。
NestJS 默認使用 JavaScript 的超集 TypeScript
進行開發。
環境準備
查看node和npm版本:
$ node --version
v15.2.1
$ npm --version
7.0.14
安裝 @nestjs/cli
使用 npm 全局安裝 @nestjs/cli
:
$ npm i -g @nestjs/cli
/usr/local/bin/nest -> /usr/local/lib/node_modules/@nestjs/cli/bin/nest.js
in/nest.js
+ @nestjs/[email protected]
added 3 packages from 3 contributors and updated 10 packages in 39.209s
使用 nest --version
命令查看 nest 當前版本:
$ nest --version
7.5.3
使用 nest new
命令創建一個名爲 nest-api
的項目:
$ nest new nest-api
⚡ We will scaffold your app in a few seconds..
CREATE nest-api/.eslintrc.js (630 bytes)
CREATE nest-api/.prettierrc (51 bytes)
CREATE nest-api/README.md (3339 bytes)
CREATE nest-api/nest-cli.json (64 bytes)
CREATE nest-api/package.json (1962 bytes)
CREATE nest-api/tsconfig.build.json (97 bytes)
CREATE nest-api/tsconfig.json (339 bytes)
CREATE nest-api/src/app.controller.spec.ts (617 bytes)
CREATE nest-api/src/app.controller.ts (274 bytes)
CREATE nest-api/src/app.module.ts (249 bytes)
CREATE nest-api/src/app.service.ts (142 bytes)
CREATE nest-api/src/main.ts (208 bytes)
CREATE nest-api/test/app.e2e-spec.ts (630 bytes)
CREATE nest-api/test/jest-e2e.json (183 bytes)
? Which package manager would you ❤️ to use? npm
▸▹▹▹▹ Installation in progress... ☕
🚀 Successfully created project nest-api
👉 Get started with the following commands:
$ cd nest-api
$ npm run start
Thanks for installing Nest 🙏
Please consider donating to our open collective
to help us maintain this package.
🍷 Donate: https://opencollective.com/nest
啓動項目
進入項目,並啓動項目
$ cd nest-api
$ npm run start
> [email protected] start
> nest start
[Nest] 95920 - 2020/12/02 下午4:17:34 [NestFactory] Starting Nest application...
[Nest] 95920 - 2020/12/02 下午4:17:34 [InstanceLoader] AppModule dependencies initialized +18ms
[Nest] 95920 - 2020/12/02 下午4:17:34 [RoutesResolver] AppController {}: +9ms
[Nest] 95920 - 2020/12/02 下午4:17:34 [RouterExplorer] Mapped {, GET} route +4ms
[Nest] 95920 - 2020/12/02 下午4:17:34 [NestApplication] Nest application successfully started +3ms
查看啓動效果:
(1)打開瀏覽器,訪問 http://localhost:3000/
就可以看到頁面輸出了 Hello World!
文字。
(2)在終端使用 curl
請求:
$ curl -i localhost:3000
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 12
ETag: W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE"
Date: Wed, 02 Dec 2020 08:18:21 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Hello World!%
可以看到, 輸出了 Hello World!
字符串。
使用 -i
參數,表示要輸出 header 頭信息。
在 header 頭信息中,我們可以看到,X-Powered-By
值爲 Express
, 就是告訴我們這個網站或框架底層是 Express
框架。
Express 是一個基於 Node.js 平臺,快速、開放、極簡的 Web 開發框架。
項目結構
查看一下項目結構:
$ ll nest-api
total 1432
-rw-r--r-- 1 wangtom staff 3.3K 12 2 16:14 README.md
drwxr-xr-x 15 wangtom staff 480B 12 2 16:17 dist/
-rw-r--r-- 1 wangtom staff 64B 12 2 16:14 nest-cli.json
drwxr-xr-x 593 wangtom staff 19K 12 2 16:15 node_modules/
-rw-r--r-- 1 wangtom staff 695K 12 2 16:15 package-lock.json
-rw-r--r-- 1 wangtom staff 1.9K 12 2 16:15 package.json
drwxr-xr-x 7 wangtom staff 224B 12 2 16:14 src/
drwxr-xr-x 4 wangtom staff 128B 12 2 16:14 test/
-rw-r--r-- 1 wangtom staff 97B 12 2 16:14 tsconfig.build.json
-rw-r--r-- 1 wangtom staff 339B 12 2 16:14 tsconfig.json
可以使用 tree 命令查看項目的目錄結構:
比如使用 tree ./nest-api -L 1
, 查看1級目錄結構。
$ tree ./nest-api -L 1
./nest-api
├── README.md
├── dist/
├── nest-cli.json
├── node_modules/
├── package-lock.json
├── package.json
├── src/
├── test/
├── tsconfig.build.json
└── tsconfig.json
4 directories, 6 files
項目的結構如下:
./nest-api
├── README.md
├── nest-cli.json
├── node_modules/
├── package-lock.json
├── package.json
├── src/ # 源碼目錄
│ ├── app.controller.spec.ts # 控制器測試文件
│ ├── app.controller.ts # 控制器類
│ ├── app.module.ts # 模塊
│ ├── app.service.ts # 服務類
│ └── main.ts # 入口文件
├── test/ # 測試代碼目錄
│ ├── app.e2e-spec.ts
│ └── jest-e2e.json
├── tsconfig.build.json
└── tsconfig.json
可以看到,和 Angular 的項目結構很相似。
查看項目的入口文件 src/main.ts
, 定義了一個異步方法(bootstrap)來啓動應用,默認監聽端口 3000
:
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
控制器: app.controller.ts
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
控制器中定義了一個名爲 getHello()
的方法,使用 @Get
註解,表示可以通過 Get 方法訪問。
控制器構造方法中引入了私有隻讀的服務類 AppService
, 在 getHello()
方法中調動了服務類(AppService)中的 getHello()
方法。
服務類: app.service.ts
// app.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
在服務類AppService中,定義了 getHello()
方法,該方法只返回了字符串 Hello World!
。
將代碼提交到 gitee
爲了方便管理代碼,可以將代碼提交到 github 或 gitee 代碼託管網站中保存。這裏我提交到 gitee 網站。
查看當前的 git 版本:
$ git --version
git version 2.23.0
初始化 git 倉庫:
$ git init
Reinitialized existing Git repository in /Users/wangtom/Code/nest-api/.git/
提示 git repository 已經存在了。說明在使用 nest new 命令創建這個項目時,就已經幫我們初始化了git倉庫了。
提交代碼,將遠程源設置爲 gitee.com 的倉庫。 需要先在 gitee.com 網站創建好自己的倉庫(【新建倉庫】)。
比如,我們已經在 gitee 創建了一個名爲 nest-api 的新倉庫,直接執行 git remote add origin [email protected]:wangyongtao/nest-api.git 即可。
$ git commit -a "init"
$ git remote add origin [email protected]:wangyongtao/nest-api.git
$ git pull origin
You asked to pull from the remote 'origin', but did not specify
a branch. Because this is not the default configured remote
for your current branch, you must specify a branch on the command line.
$ git pull origin master
From gitee.com:wangyongtao/nest-api
* branch master -> FETCH_HEAD
fatal: refusing to merge unrelated histories
出錯了,提示不能合併不相干的歷史記錄。網上一搜,找到解決辦法,增加個 --allow-unrelated-histories
參數。
$ git pull origin master --allow-unrelated-histories
From gitee.com:wangyongtao/nest-api
* branch master -> FETCH_HEAD
CONFLICT (add/add): Merge conflict in README.md
Auto-merging README.md
CONFLICT (add/add): Merge conflict in .gitignore
Auto-merging .gitignore
Automatic merge failed; fix conflicts and then commit the result.
有衝突,打開代碼文件,解決衝突代碼後保存文件。提交代碼後推送到遠程(master)。
$ git add .
$ git commit -am "MERGE"
[master 5347fd5] MERGE
$ git push origin master
打開網址 https://gitee.com/wangyongtao/nest-api 就可看到提交的代碼了。
小試牛刀
熟悉了項目目錄結構與基本運行代碼後,我們來增加一些自己的方法,感受一個這個框架。
推薦使用 Visual Studio Code
編輯器來編輯代碼。
(1) 自定義一個返回當前版本的接口,獲取當前應用的版本:
修改控制器文件 src/app.controller.ts
:
// app.controller.ts
// 導入 Post
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
// 自定義 getVersion 方法:
@Get('/version')
getVersion(): Object {
return this.appService.getVersion();
}
// 自定義 postIndex 方法:
@Post('/api')
postIndex(): Object {
return this.appService.getVersion();
}
}
在控制器文件 src/app.controller.ts
中:
新增了一個使用 @Get
註解的 getVersion()
方法,可以通過Get訪問,路由爲 “/version”。 新增了一個使用 @Post
註解的 postIndex()
方法,可以通過Post訪問, 路由爲 “/api”。
修改服務類文件 app.service.ts
:
新增一個名爲 getVersion()
的方法,返回 Object 格式的json數據。
// app.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
// 自定義:獲取版本
getVersion(): Object {
return {
code: 200,
msg: "OK",
data: {
version: "0.0.1"
},
}
}
}
代碼修改好後,使用 Control
+ C
結束終端運行。
這次我們使用 npm run start:dev
啓動項目,這樣項目裏的文件有修改會自動重啓服務:
(更多的命令可以在項目 package.json 文件的 scripts 部分看到)
$ npm run start:dev
[下午4:56:14] Starting compilation in watch mode...
[下午4:56:17] Found 0 errors. Watching for file changes.
[Nest] 2491 - 2020/12/02 下午4:56:18 [NestFactory] Starting Nest application...
[Nest] 2491 - 2020/12/02 下午4:56:18 [InstanceLoader] AppModule dependencies initialized +20ms
[Nest] 2491 - 2020/12/02 下午4:56:18 [RoutesResolver] AppController {}: +7ms
[Nest] 2491 - 2020/12/02 下午4:56:18 [RouterExplorer] Mapped {, GET} route +3ms
[Nest] 2491 - 2020/12/02 下午4:56:18 [NestApplication] Nest application successfully started +3ms
...
啓動成功了。現在我們使用 curl
命令分別來請求這幾個路由地址:
請求 “localhost:3000/version”:
# 項目默認的,首頁
$ curl localhost:3000
Hello World!%
# 默認GET請求'/version': 存在,返回預期的結果
$ curl localhost:3000/version
{"code":200,"msg":"OK","data":{"version":"0.0.1"}}%
# 改成POST請求'/version': 不存在,框架自帶的錯誤提示
$ curl -X POST localhost:3000/version
{"statusCode":404,"message":"Cannot POST /version","error":"Not Found"}%
請求 “localhost:3000/api”:
# 使用 POST 請求 '/api': 存在,返回預期的結果
$ curl -X POST localhost:3000/api
{"code":200,"msg":"OK","data":{"version":"0.0.1"}}%
# 改成 GET 請求 '/api': 不存在,框架自帶的錯誤提示
$ curl localhost:3000/api
{"statusCode":404,"error":"Not Found","message":"Cannot GET /api"}%
代碼請見:https://gitee.com/wangyongtao/nest-api
參考 References
https://my.oschina.net/wangyongtao
https://blog.csdn.net/cnwyt
https://nodejs.org/en/download/
https://docs.nestjs.com/first-steps
更新記錄 Change log
2018.12.18 新增本文檔,使用 nestjs 5.7.1 版本。 2019.06.13 修改內容,並更新 nestjs 至 6.5 版本。 2020.12.01 完善內容,並更新 nestjs 至 7.5 版本。
感謝閱讀,如有問題請留言。
[END]