Nestjs框架快速入門之項目搭建與小試牛刀

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]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章