Contents

การฉีดบริการ 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 ใหม่ที่มีชื่อที่กำหนด

การกำหนดค่าปัจจุบันของโครงการของคุณควรสอดคล้องกับภาพประกอบที่แสดงในการแสดงกราฟิกที่ให้ไว้ด้านล่าง:

/th/images/nest-js-project-skeleton.jpg

เพื่อฝึกฝนทักษะในการบูรณาการบริการต่างๆ ในโมดูลที่แตกต่างกัน จำเป็นต้องสร้างโมดูลแยกกันสองโมดูล ได้แก่ โมดูล-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”

/th/images/nest-js-project-skeleton-with-modules.jpg

การส่งออกบริการจากโมดูล 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 ซึ่งมักจะเกี่ยวข้องกับโมดูลหลายโมดูลที่พึ่งพาซึ่งกันและกันซึ่งต้องการการเข้าถึงฟังก์ชันการทำงานของกันและกัน

ประโยชน์ของการฉีดข้ามโมดูล

การรวมบริการโดยการเรียกใช้โดยตรงอาจปรากฏเป็นตัวเลือกที่เหมาะสมในตอนแรก อย่างไรก็ตาม มันมักจะส่งผลให้เกิดความซับซ้อนมากขึ้น ยากต่อการบำรุงรักษา และถูกจำกัดในสถาปัตยกรรมขอบเขตเมื่อเวลาผ่านไป

แท้จริงแล้ว การใช้งานการฉีดข้ามโมดูลช่วยส่งเสริมระบบที่เหนียวแน่นและปรับเปลี่ยนได้มากขึ้น โดยการเพิ่มความเป็นโมดูลและอำนวยความสะดวกในการใช้ส่วนประกอบซ้ำ นอกจากนี้ วิธีการนี้ยังรวมการพึ่งพา เพิ่มความเป็นไปได้ของการทดสอบ และช่วยให้ได้การออกแบบทางสถาปัตยกรรมที่เชื่อมโยงอย่างหลวมๆ ที่สามารถรองรับการเติบโตได้