การฉีดบริการ Nest.js จากโมดูลอื่น
การแทรกบริการจากโมดูล Nest.js อื่นเกี่ยวข้องกับขั้นตอนไม่กี่ขั้นตอนเพื่อให้แน่ใจว่าการฉีดการขึ้นต่อกันและการจัดระเบียบโมดูลเหมาะสม ใช้โมดูลตัวอย่างสองโมดูล เพื่อเรียนรู้วิธีการทำงานของกระบวนการส่งออกและนำเข้าบริการ
การสร้างโครงการ Nest.js
หากต้องการสร้างแอปพลิเคชัน Nest.js ตรวจสอบให้แน่ใจว่าได้ติดตั้ง Command Line Interface (CLI) ไว้ในระบบของคุณแล้ว ในกรณีที่ไม่เป็นเช่นนั้น ให้รันคำสั่งต่อไปนี้เพื่อตั้งค่า CLI:
npm install -g @nestjs/cli
หากต้องการสร้างโปรเจ็กต์ Nest.js ใหม่โดยใช้ Nest.js Command Line Interface (CLI) ให้ดำเนินการตามขั้นตอนต่อไปนี้:1. ติดตั้ง Nest.js CLI โดยรันคำสั่ง “npm install-g @nestjs/cli” หรือ “@yarn global add Nestjs-cli” ซึ่งจะช่วยให้คุณสามารถจัดการและโต้ตอบกับโครงการ Nest.js ของคุณได้จากบรรทัดคำสั่ง2. รันคำสั่ง “nest new” เพื่อสร้างโปรเจ็กต์ Nest.js ใหม่ในไดเร็กทอรีที่ระบุ การกำหนดค่าเริ่มต้นสำหรับโปรเจ็กต์ที่สร้างขึ้นใหม่ได้รับการตั้งค่าแล้วและพร้อมสำหรับการพัฒนา
nest new <project-name>
เมื่อดำเนินการตามคำสั่งที่ให้มา เราอาจแทนที่’‘ด้วยชื่อที่พวกเขาเลือกเพื่อสร้างสภาพแวดล้อมการพัฒนา Nest.js ใหม่ที่มีชื่อที่กำหนด
การกำหนดค่าปัจจุบันของโครงการของคุณควรสอดคล้องกับภาพประกอบที่แสดงในการแสดงกราฟิกที่ให้ไว้ด้านล่าง:
เพื่อฝึกฝนทักษะในการบูรณาการบริการต่างๆ ในโมดูลที่แตกต่างกัน จำเป็นต้องสร้างโมดูลแยกกันสองโมดูล ได้แก่ โมดูล-a และโมดูล-b พร้อมด้วยบริการที่มาคู่กันและไฟล์ตัวควบคุมสำหรับแต่ละโมดูล
รันคำสั่งนี้เพื่อสร้างโมดูล-a:
nest generate module module-a
และรันคำสั่งเทียบเท่าสำหรับ module-b:
nest generate module module-b
หากต้องการสร้างไฟล์ที่จำเป็นสำหรับ module-a ให้ดำเนินการคำสั่งต่อไปนี้:
nest generate service module-a && nest generate controller module-a
และรันคำสั่งเทียบเท่าสำหรับ module-b:
nest generate service module-b && nest generate controller module-b
โครงสร้างของไดเร็กทอรีโปรเจ็กต์ปัจจุบันของคุณควรมีลักษณะคล้ายกับการจัดเรียงตามลำดับชั้น ซึ่งประกอบด้วยไดเร็กทอรีย่อยหลักสองไดเร็กทอรี ได้แก่ “src/module-a” และ “src/module-b”
การส่งออกบริการจากโมดูล A
เพื่อที่จะแยกส่วนประกอบ Service-A ออกจาก Module-A และทำให้สามารถเข้าถึงได้เพื่อใช้ที่อื่นภายในแอปพลิเคชัน เราต้องรวมองค์ประกอบดังกล่าวไว้ในรายการภายใต้"ส่งออก"ในไฟล์โมดูลของ Module-A (เช่น Module-A. module.ts) โดยทั่วไป เมื่อใช้ Nest.js Command Line Interface (CLI) จะไม่มีอาร์เรย์ “ส่งออก” ที่กำหนดไว้ล่วงหน้าพร้อมกับมัณฑนากร “@Module” ดังนั้นไฟล์โมดูลผลลัพธ์ที่ได้จะแสดงโครงสร้างที่คล้ายกับดังต่อไปนี้:
// module-a.module.ts
import { Module } from '@nestjs/common';
import { ModuleAService } from './module-a.service';
import { ModuleAController } from './module-a.controller';
@Module({
providers: [ModuleAService],
controllers: [ModuleAController],
})
export class ModuleAModule {}
หากต้องการเปิดใช้งานการเข้าถึง module-a.service.ts
โดยโมดูลอื่นที่นำเข้า module-a
ควรสร้างอาร์เรย์ aexports ภายในตัวตกแต่ง @Module
และควรเพิ่ม ModuleAService
เข้าไป
ชอบเช่นนั้น:
import { Module } from '@nestjs/common';
import { ModuleAService } from './module-a.service';
import { ModuleAController } from './module-a.controller';
@Module({
providers: [ModuleAService],
controllers: [ModuleAController],
exports: [ModuleAService],
})
export class ModuleAModule {}
เพื่อทำการทดสอบบริการ module-a
คุณสามารถสร้างไฟล์ใหม่ชื่อ module-a.service.ts
ภายในไดเร็กทอรีเดียวกันกับไฟล์อื่นๆ ในโปรเจ็กต์นี้ ไฟล์นี้จะมีฟังก์ชันง่ายๆ ที่ใช้คลาส ModuleAService
และสาธิตการทำงานของมัน
import { Injectable } from '@nestjs/common';
@Injectable()
export class ModuleAService {
getHello(): string {
return 'Hello from Module A!';
}
}
ข้อความที่ให้มาดูเหมือนจะเขียนด้วยภาษาพูดและขาดความประณีต นี่คือความพยายามในการเรียบเรียงถ้อยคำใหม่ให้สวยงามยิ่งขึ้น:เพื่อให้มั่นใจถึงการทำงานที่เหมาะสมของบริการนี้ เราขอแนะนำให้เรียกใช้ฟังก์ชันดังกล่าวภายในโมดูลที่ระบุ (โมดูล-b) ภายหลังจากการฉีดบริการ-a การทำเช่นนี้อาจตรวจสอบการบูรณาการบริการดังกล่าวได้สำเร็จ
การนำเข้าบริการเข้าสู่โมดูล B
ในการที่จะนำเข้าโมดูลหนึ่งไปยังอีกโมดูลหนึ่ง จะต้องแสดงรายการไว้ในการนำเข้าของตัวตกแต่ง @Module
ของโมดูลที่รับ ดังนั้น ในกรณีที่ module-a ถูกนำเข้าโดย module-b จะต้องเพิ่มโมดูลนั้นลงในอาร์เรย์ imports
ภายในตัวตกแต่ง @Module
ของ module-b
ในการใช้โมดูลที่นำเข้าในโปรเจ็กต์ Nest.js เราจะต้องสร้างอาร์เรย์ นำเข้า
ด้วยตนเองภายในไฟล์โมดูลแอปพลิเคชัน Nest.js Command Line Interface (CLI) ไม่มีฟังก์ชันการทำงานนี้ตามค่าเริ่มต้น ซึ่งจำเป็นต้องมีการแทรกแซงด้วยตนเองเพื่อรวมฟังก์ชันดังกล่าว
แท้จริงแล้ว กระบวนการนี้เกี่ยวข้องกับการนำเข้าโมดูลหลักจากไฟล์ “module-a.module.ts” ไปยังโมดูลรับที่อยู่ใน “module-b.module.ts” หลังจากนั้น คำสั่งการนำเข้าจะถูกสร้างขึ้นภายในโค้ดของโมดูลที่ได้รับและเพิ่มลงในอาเรย์เฉพาะ หลังจากนั้นโมดูลที่ต้องการ ซึ่งก็คือ “ModuleAModule” จะถูกผนวกเข้ากับอาเรย์เดียวกันนั้น
// module-b.module.ts
import { Module } from '@nestjs/common';
import { ModuleBController } from './module-b.controller';
import { ModuleBService } from './module-b.service';
import { ModuleAModule } from '../module-a/module-a.module';
@Module({
imports: [ModuleAModule],
controllers: [ModuleBController],
providers: [ModuleBService],
})
export class ModuleBModule {}
จริงๆ แล้ว ให้เราดำเนินการขั้นต่อไปด้วยการเปิดไฟล์ module-b.service.ts
ในโครงการของเรา เราจะต้องนำเข้าทั้งมัณฑนากร @Inject
และคลาส ModuleAService
จากสองแหล่งที่แตกต่างกันภายในโค้ดเบสของแอปพลิเคชันของเรา โดยเฉพาะอย่างยิ่ง เราต้องได้รับรายการเหล่านี้จากแพ็คเกจ @nestjs/common
สำหรับอันแรกและตำแหน่งแยกต่างหากที่อื่นภายในโครงสร้างโครงการของเราสำหรับอันหลัง
import { Injectable, Inject } from '@nestjs/common';
import { ModuleAService } from '../module-a/module-a.service';
Inject decorator กำหนดพารามิเตอร์ให้เป็นผู้รับที่ต้องการของ dependency injector ซึ่งหมายความว่าเป็นองค์ประกอบสำคัญในการทำงานของระบบ และควรได้รับทรัพยากรหรือบริการที่จำเป็นเพื่อให้ทำงานได้อย่างมีประสิทธิภาพ
อันที่จริง ภายในบริบทของคลาส ModuleBService
จำเป็นต้องรวมข้อมูลโค้ดที่กล่าวมาข้างต้นในช่วงหัวเลี้ยวหัวต่อที่เหมาะสม
@Inject(ModuleAService)
private readonly moduleAService: ModuleAService;
การให้สิทธิ์การเข้าถึงวิธีการของ ModuleAService ได้รับการอำนวยความสะดวกผ่านบล็อกโค้ดที่ให้มา ดังนั้นจึงเปิดใช้งานการใช้งานภายใน ModuleBService
เราอาจตรวจสอบการทำงานของบริการ ซึ่งเป็นวิธี"getHello"ของ ModuleAService ผ่านการทดสอบ
// module-b.service.ts
import { Injectable, Inject } from '@nestjs/common';
import { ModuleAService } from 'src/module-a/module-a.service';
@Injectable()
export class ModuleBService {
@Inject(ModuleAService)
private readonly moduleAService: ModuleAService;
getHello(): string {
return this.moduleAService.getHello();
}
}
อันที่จริง ให้เราดำเนินการแก้ไขเนื้อหาของไฟล์ module-b.controller.ts โดยการแทนที่โค้ดที่มีอยู่ด้วยข้อมูลโค้ดที่ให้มา
// module-b.controller.ts
import { Controller, Get } from '@nestjs/common';
import { ModuleBService } from './module-b.service';
@Controller('module-b')
export class ModuleBController {
constructor(private readonly moduleBService: ModuleBService) {}
@Get('/hello')
getHello(): string {
return this.moduleBService.getHello();
}
}
ข้อมูลโค้ดที่ให้ไว้จะสร้างกลไกการจัดการคำขอ HTTP GET สำหรับฟังก์ชัน"getHello"ซึ่งมีหน้าที่ในการดึงและประมวลผลข้อมูลที่เกี่ยวข้องกับคำขอหรืออินพุตเฉพาะของผู้ใช้
ท้ายที่สุด ให้ดำเนินการคำขอ GET โดยใช้ cURL ไปที่ http://localhost:3000/module-b/hello คำสั่งจะแสดงข้อความ “Hello from Module A!” ในคอนโซล
การแทรกบริการที่ประสบความสำเร็จไปยังโมดูลอื่นนั้นมีประโยชน์อย่างยิ่งเมื่อพัฒนา API ภายใน Nest.js ซึ่งมักจะเกี่ยวข้องกับโมดูลหลายโมดูลที่พึ่งพาซึ่งกันและกันซึ่งต้องการการเข้าถึงฟังก์ชันการทำงานของกันและกัน
ประโยชน์ของการฉีดข้ามโมดูล
การรวมบริการโดยการเรียกใช้โดยตรงอาจปรากฏเป็นตัวเลือกที่เหมาะสมในตอนแรก อย่างไรก็ตาม มันมักจะส่งผลให้เกิดความซับซ้อนมากขึ้น ยากต่อการบำรุงรักษา และถูกจำกัดในสถาปัตยกรรมขอบเขตเมื่อเวลาผ่านไป
แท้จริงแล้ว การใช้งานการฉีดข้ามโมดูลช่วยส่งเสริมระบบที่เหนียวแน่นและปรับเปลี่ยนได้มากขึ้น โดยการเพิ่มความเป็นโมดูลและอำนวยความสะดวกในการใช้ส่วนประกอบซ้ำ นอกจากนี้ วิธีการนี้ยังรวมการพึ่งพา เพิ่มความเป็นไปได้ของการทดสอบ และช่วยให้ได้การออกแบบทางสถาปัตยกรรมที่เชื่อมโยงอย่างหลวมๆ ที่สามารถรองรับการเติบโตได้