ขยาย API ที่มีอยู่ด้วยจุดปลายที่กำหนดเอง


12

ฉันกำลังสร้าง API สำหรับลูกค้าหลายคน จุดสิ้นสุดหลักเช่นเดียวกับ/usersที่ใช้โดยลูกค้าทุกคน แต่จุดปลายบางอย่างขึ้นอยู่กับการปรับแต่งของแต่ละบุคคล ดังนั้นอาจเป็นไปได้ว่าผู้ใช้ Aต้องการจุดปลายพิเศษ/groupsและไม่มีลูกค้ารายอื่นที่จะมีคุณสมบัติดังกล่าว เช่นเดียวกับ sidenoteลูกค้าแต่ละรายจะใช้สคีมาฐานข้อมูลของเขาเองเนื่องจากคุณสมบัติพิเศษเหล่านั้น

ฉันใช้ NestJs (ด่วนภายใต้ประทุน) เป็นการส่วนตัว ดังนั้นapp.moduleปัจจุบันลงทะเบียนโมดูลหลักทั้งหมดของฉัน (พร้อมจุดสิ้นสุดของตนเองเป็นต้น)

import { Module } from '@nestjs/common';

import { UsersModule } from './users/users.module'; // core module

@Module({
  imports: [UsersModule]
})
export class AppModule {}

ฉันคิดว่าปัญหานี้ไม่เกี่ยวข้องกับ NestJs ดังนั้นคุณจะจัดการกับเรื่องนี้อย่างไรในทางทฤษฎี?

โดยทั่วไปฉันต้องการโครงสร้างพื้นฐานที่สามารถให้ระบบพื้นฐานได้ ไม่มีจุดสิ้นสุดหลักอีกต่อไปเพราะส่วนขยายแต่ละรายการไม่ซ้ำกันและ/usersอาจมีการใช้งานหลายอย่าง เมื่อพัฒนาฟีเจอร์ใหม่แอปพลิเคชันหลักไม่ควรสัมผัส ส่วนขยายควรรวมตัวเองหรือควรรวมเข้าด้วยกันเมื่อเริ่มต้น ระบบหลักจัดส่งโดยไม่มีจุดสิ้นสุด แต่จะถูกขยายจากไฟล์ภายนอกเหล่านั้น

ความคิดบางอย่างมาถึงใจของฉัน


วิธีแรก:

แต่ละนามสกุลแสดงถึงที่เก็บใหม่ กำหนดพา ธ ไปยังโฟลเดอร์ภายนอกที่กำหนดเองซึ่งถือโครงการส่วนขยายทั้งหมดนั้น ไดเรกทอรีที่กำหนดเองนี้จะมีโฟลเดอร์ที่groupsมีgroups.module

import { Module } from '@nestjs/common';

import { GroupsController } from './groups.controller';

@Module({
  controllers: [GroupsController],
})
export class GroupsModule {}

API ของฉันสามารถวนซ้ำผ่านไดเรกทอรีนั้นและพยายามนำเข้าแต่ละไฟล์โมดูล

  • ข้อดี:

    1. รหัสที่กำหนดเองจะถูกเก็บห่างจากพื้นที่เก็บข้อมูลหลัก
  • ข้อเสีย:

    1. NestJs ใช้ typescript ดังนั้นฉันต้องรวบรวมรหัสก่อน ฉันจะจัดการการสร้าง API และการสร้างจากแอปที่กำหนดเองได้อย่างไร (ระบบปลั๊กแอนด์เพลย์)

    2. ส่วนขยายที่กำหนดเองนั้นหลวมเพราะมีไฟล์ typescript บางตัวเท่านั้น เนื่องจากพวกเขาไม่สามารถเข้าถึงไดเร็กทอรี node_modules ของ API ตัวแก้ไขของฉันจะแสดงข้อผิดพลาดให้ฉันเพราะมันไม่สามารถแก้ไขการพึ่งพาแพ็คเกจภายนอกได้

    3. ส่วนขยายบางอย่างอาจดึงข้อมูลจากส่วนขยายอื่น บางทีบริการกลุ่มจำเป็นต้องเข้าถึงบริการผู้ใช้ สิ่งต่าง ๆ อาจจะมีเล่ห์เหลี่ยมที่นี่


วิธีที่สอง: เก็บส่วนขยายแต่ละรายการไว้ในโฟลเดอร์ย่อยของโฟลเดอร์ src ของ API แต่เพิ่มโฟลเดอร์ย่อยนี้ไปยังไฟล์. gitignore ตอนนี้คุณสามารถเก็บส่วนขยายไว้ใน API

  • ข้อดี:

    1. โปรแกรมแก้ไขของคุณสามารถแก้ไขการอ้างอิง

    2. ก่อนที่จะปรับใช้รหัสของคุณคุณสามารถเรียกใช้คำสั่ง build และจะมีการกระจายเดียว

    3. คุณสามารถเข้าถึงบริการอื่น ๆ ได้อย่างง่ายดาย ( /groupsต้องการค้นหาผู้ใช้ด้วย ID)

  • ข้อเสีย:

    1. เมื่อพัฒนาคุณต้องคัดลอกไฟล์ที่เก็บข้อมูลของคุณภายในโฟลเดอร์ย่อยนั้น หลังจากเปลี่ยนแปลงบางสิ่งคุณต้องคัดลอกไฟล์เหล่านี้ไปมาและแทนที่ไฟล์เก็บข้อมูลของคุณด้วยไฟล์ที่อัปเดต

แนวทางที่สาม:

ภายในโฟลเดอร์ที่กำหนดเองภายนอกส่วนขยายทั้งหมดเป็น API แบบสแตนด์อโลนที่สมบูรณ์ API หลักของคุณจะให้ข้อมูลการตรวจสอบสิทธิ์และอาจทำหน้าที่เป็นพร็อกซีเพื่อเปลี่ยนเส้นทางคำขอขาเข้าไปยัง API เป้าหมาย

  • ข้อดี:

    1. ส่วนขยายใหม่สามารถพัฒนาและทดสอบได้อย่างง่ายดาย
  • ข้อเสีย:

    1. การใช้งานจะยุ่งยาก คุณจะมี API หลักและ API ส่วนขยายnเริ่มกระบวนการของตนเองและรับฟังพอร์ต

    2. ระบบพร็อกซีอาจยุ่งยาก หากไคลเอนต์ร้องขอ/usersพร็อกซีจำเป็นต้องทราบว่าส่วนขยาย API ใดรับฟังจุดปลายทางนั้นให้เรียกใช้ API นั้นและส่งต่อการตอบกลับนั้นกลับไปยังไคลเอนต์

    3. เพื่อป้องกัน API ส่วนขยาย (การตรวจสอบความถูกต้องถูกจัดการโดย API หลัก) พร็อกซีต้องเปิดเผยข้อมูลลับกับ API เหล่านั้น ดังนั้นส่วนขยาย API จะส่งคำขอที่เข้ามาเฉพาะหากมีการให้ข้อมูลลับที่ตรงกันจากพรอกซี


วิธีที่สี่:

Microservices อาจช่วยได้ ฉันได้รับคำแนะนำจากที่นี่https://docs.nestjs.com/microservices/basics

ฉันสามารถมี microservice สำหรับการจัดการผู้ใช้การจัดการกลุ่มและอื่น ๆ และใช้บริการเหล่านั้นโดยสร้าง api / gateway / proxy ขนาดเล็กที่เรียก microservices เหล่านั้น

  • ข้อดี:

    1. ส่วนขยายใหม่สามารถพัฒนาและทดสอบได้อย่างง่ายดาย

    2. แยกความกังวล

  • ข้อเสีย:

    1. การใช้งานจะยุ่งยาก คุณจะมี API หลักและn microservices เริ่มกระบวนการของตัวเองและฟังพอร์ต

    2. ดูเหมือนว่าฉันจะต้องสร้างเกตเวย์ api ใหม่สำหรับลูกค้าแต่ละรายถ้าฉันต้องการที่จะได้รับการปรับแต่ง ดังนั้นแทนที่จะขยายแอปพลิเคชันฉันจะต้องสร้าง API comsuming ที่กำหนดเองในแต่ละครั้ง ที่จะไม่แก้ปัญหา

    3. เพื่อป้องกัน API ส่วนขยาย (การตรวจสอบความถูกต้องถูกจัดการโดย API หลัก) พร็อกซีต้องเปิดเผยข้อมูลลับกับ API เหล่านั้น ดังนั้นส่วนขยาย API จะส่งคำขอที่เข้ามาเฉพาะหากมีการให้ข้อมูลลับที่ตรงกันจากพรอกซี


2
สิ่งนี้อาจช่วยgithub.com/nestjs/nest/issues/3277
คำถามที่ 3

ขอบคุณสำหรับลิงค์ แต่ฉันไม่คิดว่าฉันควรมีส่วนขยายที่กำหนดเองภายในรหัสของฉัน ฉันจะตรวจสอบว่า microservices จะแก้ปัญหาdocs.nestjs.com/microservices/basics หรือไม่
hrp8sfH4xQ4

ฉันคิดว่าปัญหาของคุณเกี่ยวข้องกับการให้สิทธิ์มากกว่าการพักผ่อน
adnanmuttaleb

@ adnanmuttaleb คุณคิดจะอธิบายว่าทำไม =
hrp8sfH4xQ4

คำตอบ:


6

มีหลายวิธีในการนี้ สิ่งที่คุณต้องทำคือหาว่าเวิร์กโฟลว์ใดเหมาะที่สุดสำหรับทีมองค์กรและลูกค้าของคุณ

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

สิ่งที่คุณต้องการคือไฟล์หลักและไฟล์รายการแพ็คเกจต่อการติดตั้งแบบกำหนดเอง คุณสามารถพัฒนาและปรับใช้เวอร์ชันใหม่ได้อย่างอิสระและคุณสามารถโหลดเวอร์ชันใหม่เมื่อคุณต้องการบนฝั่งไคลเอ็นต์

เพื่อความราบรื่นที่เพิ่มขึ้นคุณสามารถใช้ไฟล์การกำหนดค่าเพื่อแมปโมดูลกับเส้นทางและเขียนสคริปต์ตัวสร้างเส้นทางทั่วไปเพื่อทำส่วนใหญ่ของ bootstrapping

เนื่องจากแพ็คเกจสามารถเป็นอะไรก็ได้การอ้างอิงข้ามภายในแพ็คเกจจะทำงานได้โดยไม่ยุ่งยาก คุณเพียงแค่ต้องได้รับการรักษาเมื่อมีการเปลี่ยนแปลงและการจัดการเวอร์ชัน

อ่านเพิ่มเติมเกี่ยวกับแพ็คเกจส่วนตัวได้ที่นี่: แพ็คเกจส่วนตัว NPM

ตอนนี้การลงทะเบียน NPM ส่วนตัวจะเสียค่าใช้จ่าย แต่ถ้านั่นเป็นปัญหาก็มีตัวเลือกอื่น ๆ เช่นกัน โปรดตรวจสอบบทความนี้สำหรับทางเลือกบางอย่าง - ฟรีและจ่ายเงิน

วิธีที่จะมีการลงทะเบียน NPM ส่วนตัวของคุณ

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

ฉันได้เขียนการใช้งานอ้างอิงอย่างง่าย ๆ สำหรับระบบดังกล่าว:

เฟรมเวิร์ก: locomotion service locator

ตัวอย่างปลั๊กอินตรวจสอบ palindromes: ตัวอย่างปลั๊กอิน locomotion

แอปพลิเคชันที่ใช้เฟรมเวิร์กเพื่อค้นหาปลั๊กอิน: ตัวอย่างแอป locomotion

คุณสามารถเล่นกับสิ่งนี้โดยรับมันจาก npm โดยใช้npm install -s locomotionคุณจะต้องระบุplugins.jsonไฟล์ที่มีสคีมาต่อไปนี้:

{
    "path": "relative path where plugins should be stored",
    "plugins": [
        { 
           "module":"name of service", 
           "dir":"location within plugin folder",
           "source":"link to git repository"
        }
    ]
}

ตัวอย่าง:

{
    "path": "./plugins",
    "plugins": [
        {
            "module": "palindrome",
            "dir": "locomotion-plugin-example",
            "source": "https://github.com/drcircuit/locomotion-plugin-example.git"
        }
    ]
}

โหลดแบบนี้: const loco = require ("locomotion");

จากนั้นส่งคืนสัญญาที่จะแก้ไขวัตถุตัวระบุตำแหน่งบริการซึ่งมีวิธีการระบุตำแหน่งเพื่อรับบริการของคุณ:

loco.then((svc) => {
    let pal = svc.locate("palindrome"); //get the palindrome service
    if (pal) {
        console.log("Is: no X in Nixon! a palindrome? ", (pal.isPalindrome("no X in Nixon!")) ? "Yes" : "no"); // test if it works :)
    }
}).catch((err) => {
    console.error(err);
});

โปรดทราบว่านี่เป็นเพียงการนำไปใช้อ้างอิงและไม่เพียงพอสำหรับการใช้งานที่ร้ายแรง อย่างไรก็ตามรูปแบบยังคงใช้ได้และแสดงส่วนสำคัญของการเขียนกรอบประเภทนี้

ตอนนี้สิ่งนี้จะต้องขยายออกไปด้วยการสนับสนุนสำหรับการกำหนดค่าปลั๊กอินการเริ่มต้นตรวจสอบข้อผิดพลาดอาจเพิ่มการสนับสนุนสำหรับการฉีดพึ่งพาและอื่น ๆ


ขอบคุณ มีปัญหาสองประการเกิดขึ้นดูเหมือนว่าเราจะใช้เวลาในการตรวจสอบและต้องตั้งค่ารีจิสทรีที่โฮสต์ด้วยตนเอง สิ่งที่สองคือส่วนตัว npm ไม่ฟรีอีกต่อไป ฉันหวังว่าจะหาทางออกทางเทคนิคขั้นพื้นฐาน แต่ +1 สำหรับแนวคิด :)
hrp8sfH4xQ4

1
เพิ่มการใช้งานอ้างอิงของโซลูชันพื้นฐานสำหรับระบบประเภทนี้
Espen

3

ฉันจะไปหาแพ็คเกจภายนอก

คุณสามารถจัดโครงสร้างแอปของคุณให้มีpackagesโฟลเดอร์ ฉันจะสร้างบิลด์แพ็กเกจภายนอกที่รวบรวมไว้ใน UMD เพื่อให้ typescript ที่คอมไพล์แล้วของคุณจะไม่มีปัญหาใด ๆ กับแพ็คเกจ แพคเกจทั้งหมดควรมีindex.jsไฟล์ในโฟลเดอร์รูทของแต่ละแพ็คเกจ

และแอพของคุณสามารถเรียกใช้ลูปผ่านโฟลเดอร์แพ็คเกจโดยใช้fsและrequireแพ็คเกจทั้งหมดindex.jsในแอปของคุณ

จากนั้นอีกครั้งการติดตั้งการพึ่งพาเป็นสิ่งที่คุณต้องดูแล ฉันคิดว่าไฟล์การกำหนดค่าในแต่ละแพ็คเกจสามารถแก้ไขได้เช่นกัน คุณสามารถมีnpmสคริปต์ที่กำหนดเองในแอพหลักเพื่อติดตั้งการขึ้นต่อกันของแพ็คเกจทั้งหมดก่อนเริ่มแอปพลิเคชัน

ด้วยวิธีนี้คุณสามารถเพิ่มแพ็คเกจใหม่ลงในแอปของคุณโดยคัดลอกวางแพคเกจลงในโฟลเดอร์แพ็คเกจและรีบูตแอป ไฟล์ typescript ที่คอมไพล์ของคุณจะไม่ถูกแตะต้องและคุณไม่จำเป็นต้องใช้ส่วนตัว npm สำหรับแพ็คเกจของคุณเอง


ขอบคุณสำหรับการตอบกลับของคุณ. ฉันคิดว่ามันฟังดูเหมือนโซลูชัน @ Espen โพสต์ไปแล้วใช่ไหม
hrp8sfH4xQ4

@ hrp8sfH4xQ4 ใช่เพื่อขยาย npmฉันเพิ่มมันหลังจากที่ได้อ่านความคิดเห็นของคุณไม่ต้องการที่จะใช้ ข้างต้นเป็นวิธีการแก้ปัญหาที่คุณสามารถทำได้เพื่อหลีกเลี่ยงบัญชีส่วนตัวส่วนตัว ยิ่งกว่านั้นฉันเชื่อว่าคุณไม่จำเป็นต้องเพิ่มแพ็คเกจที่สร้างโดยบุคคลภายนอกองค์กรของคุณ ขวา?
Kalesh Kaladharan

BTW แต่มันก็ยอดเยี่ยมที่จะสนับสนุนเช่นกัน ... อย่างใด ...
hrp8sfH4xQ4

หากคุณต้องการตัวเลือกในการเพิ่มแพ็คเกจของบุคคลที่สามnpmนั่นคือวิธีที่จะทำหรือผู้จัดการแพ็คเกจอื่น ๆ ในกรณีเช่นนี้ทางออกของฉันจะไม่เพียงพอ
Kalesh Kaladharan

หากคุณไม่รังเกียจฉันอยากจะรอวิธีการรวบรวมให้ได้มากที่สุด
hrp8sfH4xQ4
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.