什麼是Nest.js?一款輕量級JavaScript框架

什麼是Nest.js?一款輕量級JavaScript框架

管理一個大規模的應用程式可能會很繁瑣,尤其是在沒有經過良好規劃的結構和嚴格的程式碼組織策略下構建時。這可能會導致在維護過程中出現災難,並應盡一切努力避免。這種災難是由於隨著專案使用者基數的增長,對程式碼庫的修改和新功能的引入所引起的。

另一方面,Nest.js旨在提供解決程式碼結構和程式碼組織策略問題的解決方案。它結合了現代化和模組化的軟體工程原則。

Nest.js使用TypeScript進行型別檢查,併為構建和部署可測試、可擴充套件、鬆散耦合且易於維護的應用程式提供了一個開箱即用的軟體架構。

在本文中,我們將探討Nest.js及其可以構建的內容。我們還將解釋該框架的優缺點,以便讓您清楚為什麼公司更喜歡它而不是其他Node.js框架。最後,我們將演示如何使用Nest.js建立一個待辦事項API。

什麼是Nest.js?

Nest.js是一種快速增長的Node.js框架,用於使用Node.js構建高效、可擴充套件和企業級的後端應用程式。它以使用現代JavaScript和TypeScript產生高度可測試、可維護和可擴充套件的應用程式而聞名。

Nest.js官方標誌

Nest.js官方標誌(圖片來源:Behance

GitHub上擁有超過46.6k個星星和5.4k個Fork,並且每週下載量高達70萬次,這個框架是使用Node.js構建後端專案的熱門選擇。

如果您需要構建可擴充套件、可維護、企業級的應用程式,Nest.js是您下一個專案的完美解決方案。

在下一節中,我們將探討它的用途以及在生產中使用該框架的不同公司。

Nest.js的用途是什麼?

Nest.js是一個用於構建高度可測試和可維護後端應用程式的伺服器端Node.js框架。您可以使用Node.js建立各種型別的應用程式;唯一的限制在於應用程式的功能。

由於該框架利用了TypeScript,Nest.js在尋求發揮TypeScript型別檢查能力的團隊中特別受歡迎。而且,它易於學習和掌握,具有強大的CLI(命令列介面),可提高生產力和開發的便利性。這個強大的CLI使得快速啟動任何伺服器端專案並將其完成變得輕而易舉。

此外,Nest.js提供了詳細的文件,並且其開發者和貢獻者社羣非常活躍,願意隨時解決問題。

這些原因使得很多公司都傾向於切換到Nest.js框架。下面是一些在生產中使用該框架的知名品牌。

Roche

Roche是一家跨國醫藥公司,分為製藥和診斷兩個部門。這家美國生物科技公司在其主要網站上使用Nest.js框架,可靠地為患者提供服務並進一步擴大其業務。

Roche官方主頁

Roche官方主頁

Adidas

阿迪達斯是歐洲最大的運動服裝製造商,全球排名第二。阿迪達斯以設計和製造鞋類、服裝和配飾而聞名。由於其全球覆蓋範圍和知名度,他們決定使用高度可擴充套件的Nest.js框架來構建品牌的大規模高效應用程式。

阿迪達斯官方主頁

阿迪達斯官方主頁

Decathlon

迪卡儂是在57個國家擁有超過1,500家門店的體育用品零售商。迪卡儂選擇了Nest.js作為其網路應用程式的後端,以幫助他們擴充套件和維護現有的程式碼庫。

迪卡儂官方主頁

迪卡儂官方主頁

您可以在GitHub上找到使用Nest.js構建的其他公司、專案和工具的列表。

接下來,我們將討論為什麼您和您的公司應選擇Nest.js作為下一個專案,並介紹為什麼其他人已經使用該框架以及它的優勢。

為什麼選擇Nest.js

選擇一個框架取決於您正在開發的應用程式型別,因為不同的應用程式需要不同的工具集。

在這裡,我們將列舉選擇Nest.js作為您的Node.js框架來升級或構建下一個專案的不同原因。

  • Nest.js易於學習和掌握,特別適用於來自Angular世界的開發人員。這使得開發過程快速高效,團隊成員可以輕鬆適應任何新的開發原則和結構。
  • 該框架以出色的企業級應用程式架構而聞名,使構建高度可擴充套件和可維護的企業級應用程式變得輕而易舉。
  • 您可以輕鬆使用Nest.js構建各種型別的後端服務,包括RESTful API、GraphQL應用程式、MVC應用程式、Websockets、CLI和Cron作業。一些標準架構已經內建在Nest.js框架中。
  • 由於Nest.js使用了現代技術,如TypeScript、可靠的架構模式、優秀的文件和易於單元測試,您可以構建可擴充套件和可維護的企業級應用程式。
  • Nest.js是為構建大規模的單體和微服務應用程式而建立的,其中架構已經處理好,您只需要構建自己的業務邏輯。
  • Nest.js支援並提供基於社羣的大量nest-supported模組,以構建您選擇的任何特定功能,從TypeORM、Mongoose和GraphQL等概念到日誌記錄、驗證、快取、WebSockets等等。

接下來,我們將探討Nest.js的優缺點。通過討論好的和壞的方面,這將有助於鞏固您採用該框架的決定。

Nest.js的優缺點

在這裡,我們將列舉Nest.js的優缺點,以更好地瞭解為什麼它在Node.js生態系統中如此受歡迎。

優點

使用Nest.js的一些好處包括:

  • 強大但使用者友好:該框架對開發人員來說非常友好,即使是最複雜和強大的功能也很容易使用。Nest.js團隊設計了這個框架,讓開發人員可以快速入門,並專注於編寫業務邏輯,而框架會處理其他重要的開發方面,比如安全性
  • Angular風格的語法(後端):Angular是一個非常受歡迎的前端框架,專注於架構和結構。Nest.js作為後端的Angular,它使用Angular風格和語法來幫助您構建企業專案結構。
  • TypeScript支援:Nest.js從一開始就支援TypeScript,它解決了效能問題,並通過提供編譯錯誤和警告來快速編寫可維護的應用程式。TypeScript與VSCode很好地整合在一起,提供易於使用的開發環境。
  • 詳盡的文件:Nest.js擁有一些最好的框架文件,非常易於理解。查閱文件可以節省除錯時間,快速找到解決問題的方法。
  • 良好的架構和快速開發:Nest.js為您的應用程式提供了堅實的結構和架構,無論是建立第一個MVP還是實際應用程式,都可以為您節省時間,從而增強您的開發過程。

缺點

有句著名的名言:“每個優勢都有其不足之處”——Nest.js也不例外。因此,讓我們探討一下Nest.js的缺點。

  • 對新手來說有難度:對於不具備Angular背景的初學者開發人員來說,Nest.js可能有些棘手,需要一些時間和實踐才能學習和掌握。此外,由於並非所有JavaScript開發人員都使用TypeScript,這個框架對這些開發人員來說也可能有難度。但就像其他技術一樣,它需要時間和實踐。
  • 除錯困難:儘管TypeScript有其優點,但也會帶來許多除錯上的困擾,特別是對於TypeScript領域中的新手開發人員來說。

這就是Nest.js的優點和缺點,以及它們如何影響您選擇它作為首選框架的決策制定過程。

接下來,我們將通過使用Nest.js構建一個RESTful API來鞏固我們迄今為止學到的知識。繼續閱讀,瞭解如何開發一個待辦事項API,允許使用者建立和管理他們的待辦事項列表。

構建你的第一個Nest.js RESTful API

是時候將我們學到的關於Nest.js的知識付諸實踐,通過構建我們的第一個RESTful API來展示它的功能和簡單性。

我們將從設定框架和安裝所有必要工具開始,讓它能夠執行起來。

1. 設定Nest.js

首先,我們使用以下命令安裝Nest CLI以建立新專案:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm i -g @nestjs/cli
npm i -g @nestjs/cli
npm i -g @nestjs/cli

之後,使用以下命令建立一個新專案:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
nest new nest-todo-api
cd nest-todo-api
npm run start:dev
nest new nest-todo-api cd nest-todo-api npm run start:dev
nest new nest-todo-api
cd nest-todo-api
npm run start:dev

現在,我們已經安裝了Nest CLI併成功建立了新專案,讓我們構建我們的API。

在你選擇的任何程式碼編輯器中開啟這個專案。如果你訪問 localhost:3000,你應該會看到一個歡迎資訊,顯示一切都成功執行。

接下來,我們將設定一個MongoDB資料庫來連線和管理專案中的待辦事項資料。

在深入之前,讓我們使用以下命令生成我們建立API所需的所有檔案:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
nest generate module todos
nest generate controller todos
nest generate service todos
nest generate module todos nest generate controller todos nest generate service todos
nest generate module todos
nest generate controller todos
nest generate service todos

2. 設定MongoDB

接下來,我們將安裝並配置MongoDB以與之前建立的專案一起工作。

在本地計算機上安裝MongoDB後,執行以下命令來在我們新建立的專案中安裝Mongoose庫:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install --save @nestjs/mongoose mongoose
npm install --save @nestjs/mongoose mongoose
npm install --save @nestjs/mongoose mongoose

這就是你需要做的。

接下來,我們將生成檔案並將Mongoose引入專案和MongoDB進行通訊。

在生成其他必要檔案之前,讓我們將Mongoose引入我們的應用程式模組檔案中。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '@nestjs/mongoose';
import { TodosModule } from './todos/todos.module';
@Module({
imports: [MongooseModule.forRoot('mongodb://localhost/todos), TodosModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { MongooseModule } from '@nestjs/mongoose'; import { TodosModule } from './todos/todos.module'; @Module({ imports: [MongooseModule.forRoot('mongodb://localhost/todos), TodosModule], controllers: [AppController], providers: [AppService], }) export class AppModule {}
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '@nestjs/mongoose';
import { TodosModule } from './todos/todos.module';
@Module({
imports: [MongooseModule.forRoot('mongodb://localhost/todos), TodosModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

3. 構建模式

接下來,我們將為我們的資料庫構建資料庫模式。這個模式將指定資料在我們的資料庫中的表示方式。

讓我們在我們的todos.schema.ts檔案中定義它:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import * as mongoose from 'mongoose';
export const ItemSchema = new mongoose.Schema({
title: String,
is_completed: Boolean,
description: String,
});
import * as mongoose from 'mongoose'; export const ItemSchema = new mongoose.Schema({ title: String, is_completed: Boolean, description: String, });
import * as mongoose from 'mongoose';
export const ItemSchema = new mongoose.Schema({
title: String,
is_completed: Boolean,
description: String,
});

4. 定義介面

接下來,我們將建立一個用於型別檢查的介面。

讓我們在我們的interfaces/todo.interface.ts檔案中定義它:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { Document } from 'mongoose';
export interface Item extends Document {
id?: string;
title: string;
description?: string;
is_completed: boolean;
}
import { Document } from 'mongoose'; export interface Item extends Document { id?: string; title: string; description?: string; is_completed: boolean; }
import { Document } from 'mongoose';
export interface Item extends Document {
id?: string;
title: string;
description?: string;
is_completed: boolean;
}

5. 建立DTO

最後,我們將構建一個DTO (資料傳輸物件),定義資料將如何在網路中的物件之間傳送或傳遞。

它是一個基本類,具有和我們模式相同的屬性:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// ./dto/create-todo.ts
export class CreateItemDto {
readonly title: string;
readonly description: string;
readonly is_completed: boolean;
}
// ./dto/create-todo.ts export class CreateItemDto { readonly title: string; readonly description: string; readonly is_completed: boolean; }
// ./dto/create-todo.ts
export class CreateItemDto {
readonly title: string;
readonly description: string;
readonly is_completed: boolean;
}

6. 設定模型/服務

服務檔案負責與MongoDB資料庫進行互動和通訊。它用於在先前建立的 todos 模式中建立、檢索、更新和刪除記錄。

開啟你的服務檔案並新增以下程式碼:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { Injectable } from '@nestjs/common';
import { Todo } from './interfaces/todo.interface';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { CreateTodoDto } from './dto/create-todo.dto';
@Injectable()
export class ItemsService {
constructor(@InjectModel('Todo') private readonly todoModel: Model) {}
async findAll(): Promise<Todo[]> {
return await this.todoModel.find();
}
async findOne(id: string): Promise {
return await this.todoModel.findOne({ _id: id });
}
async create(item: CreateItemDto): Promise {
const newTodo = new this.todoModel(item);
return await newTodo.save();
}
async delete(id: string): Promise {
return await this.todoModel.findByIdAndRemove(id);
}
async update(id: string, todo: CreateTodoDto): Promise {
return await this.todoModel.findByIdAndUpdate(id, todo, { new: true });
}
}
import { Injectable } from '@nestjs/common'; import { Todo } from './interfaces/todo.interface'; import { Model } from 'mongoose'; import { InjectModel } from '@nestjs/mongoose'; import { CreateTodoDto } from './dto/create-todo.dto'; @Injectable() export class ItemsService { constructor(@InjectModel('Todo') private readonly todoModel: Model) {} async findAll(): Promise<Todo[]> { return await this.todoModel.find(); } async findOne(id: string): Promise { return await this.todoModel.findOne({ _id: id }); } async create(item: CreateItemDto): Promise { const newTodo = new this.todoModel(item); return await newTodo.save(); } async delete(id: string): Promise { return await this.todoModel.findByIdAndRemove(id); } async update(id: string, todo: CreateTodoDto): Promise { return await this.todoModel.findByIdAndUpdate(id, todo, { new: true }); } }
import { Injectable } from '@nestjs/common';
import { Todo } from './interfaces/todo.interface';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { CreateTodoDto } from './dto/create-todo.dto';
@Injectable()
export class ItemsService {
constructor(@InjectModel('Todo') private readonly todoModel: Model) {}
async findAll(): Promise<Todo[]> {
return await this.todoModel.find();
}
async findOne(id: string): Promise {
return await this.todoModel.findOne({ _id: id });
}
async create(item: CreateItemDto): Promise {
const newTodo = new this.todoModel(item);
return await newTodo.save();
}
async delete(id: string): Promise {
return await this.todoModel.findByIdAndRemove(id);
}
async update(id: string, todo: CreateTodoDto): Promise {
return await this.todoModel.findByIdAndUpdate(id, todo, { new: true });
}
}

上面的程式碼段使用Mongoose模型在我們的API上表達了CRUD (建立、讀取、更新、刪除)應用程式,以便他們訪問我們底層的MongoDB資料庫。

接下來,我們將建立我們的控制器檔案,用於處理所有邏輯和與我們上面建立的服務進行通訊。

7. 設定控制器

控制器負責處理傳入的請求並向客戶端傳送響應。

讓我們定義我們的 Todo 控制器並貼上以下程式碼段:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
} from '@nestjs/common';
import { CreateTodoDto } from './dto/create-todo.dto';
import { TodosService } from './todos.service';
import { Todo } from './interfaces/todo.interface';
@Controller('items')
export class ItemsController {
constructor(private readonly todosService: TodosService) {}
@Get()
findAll(): Promise<Todo[]> {
return this.todosService.findAll();
}
@Get(':id')
findOne(@Param('id') id): Promise {
return this.todosService.findOne(id);
}
@Post()
create(@Body() createTodoDto: CreateTodoDto): Promise {
return this.todosService.create(createTodoDto);
}
@Delete(':id')
delete(@Param('id') id): Promise {
return this.todosService.delete(id);
}
@Put(':id')
update(@Body() updateTodoDto: CreateTodoDto, @Param('id') id): Promise {
return this.todosService.update(id, updateTodoDto);
}
}
import { Controller, Get, Post, Put, Delete, Body, Param, } from '@nestjs/common'; import { CreateTodoDto } from './dto/create-todo.dto'; import { TodosService } from './todos.service'; import { Todo } from './interfaces/todo.interface'; @Controller('items') export class ItemsController { constructor(private readonly todosService: TodosService) {} @Get() findAll(): Promise<Todo[]> { return this.todosService.findAll(); } @Get(':id') findOne(@Param('id') id): Promise { return this.todosService.findOne(id); } @Post() create(@Body() createTodoDto: CreateTodoDto): Promise { return this.todosService.create(createTodoDto); } @Delete(':id') delete(@Param('id') id): Promise { return this.todosService.delete(id); } @Put(':id') update(@Body() updateTodoDto: CreateTodoDto, @Param('id') id): Promise { return this.todosService.update(id, updateTodoDto); } }
import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
} from '@nestjs/common';
import { CreateTodoDto } from './dto/create-todo.dto';
import { TodosService } from './todos.service';
import { Todo } from './interfaces/todo.interface';
@Controller('items')
export class ItemsController {
constructor(private readonly todosService: TodosService) {}
@Get()
findAll(): Promise<Todo[]> {
return this.todosService.findAll();
}
@Get(':id')
findOne(@Param('id') id): Promise {
return this.todosService.findOne(id);
}
@Post()
create(@Body() createTodoDto: CreateTodoDto): Promise {
return this.todosService.create(createTodoDto);
}
@Delete(':id')
delete(@Param('id') id): Promise {
return this.todosService.delete(id);
}
@Put(':id')
update(@Body() updateTodoDto: CreateTodoDto, @Param('id') id): Promise {
return this.todosService.update(id, updateTodoDto);
}
}

該框架使用註解來處理很多後臺功能,例如通過為RESTful API的Put、Delete、Post和Get分別提供不同的註解(@Put()@Delete()@Post()@Get())來處理框架的路由系統。

8. 使用Postman測試API

最後,我們將使用Postman測試我們新建立的API。在部署到生產伺服器之前,我們需要啟動開發伺服器以確保一切正常執行。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm run start:dev
npm run start:dev
npm run start:dev

你可以下載和執行Postman來測試你的RESTful API。

Nest.js待辦事項列表結果

Nest.js待辦事項列表結果

小結

Nest.js是一個強大的Node.js框架,也是目前最流行的TypeScript框架。

它為工程團隊提供了標準的開發架構和行業最佳實踐。開發人員可以將重複的工程流程抽象出來,專注於開發業務邏輯。

正是這些優勢促使Adidas、Roche等知名品牌選擇在其企業生產應用程式中使用該框架。

在本文中,我們為Nest.js打下了堅實的基礎,解釋了為什麼你和你的公司應該考慮轉向它。此外,我們構建了一個簡單的待辦事項RESTful API來實際展示該框架的強大之處。

現在,你可以決定Nest.js是否適合你。

評論留言