розширити існуючий API за допомогою спеціальних кінцевих точок


12

Я створюю API для кількох клієнтів. Основні кінцеві точки, як-от /users, використовує кожен клієнт, але деякі кінцеві точки покладаються на індивідуальне налаштування. Тому може бути, що користувач A хоче спеціальну кінцеву точку, /groupsі жоден інший клієнт не матиме цієї функції. Як і сторонне позначення , кожен клієнт також використовував би свою власну схему баз даних через ці додаткові можливості.

Я особисто використовую 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 та збірок за допомогою спеціальних програм? (Plug and play system)

    2. Спеціальні розширення дуже вільні, оскільки вони просто містять деякі файли машинописів. Через те, що вони не мають доступу до каталогу node_modules API, мій редактор покаже мені помилки, оскільки він не може вирішити залежність від зовнішніх пакетів.

    3. Деякі розширення можуть отримати дані з іншого розширення. Можливо, службі груп потрібно отримати доступ до служби користувачів. Тут може скластись складність.


Другий підхід: зберігайте кожне розширення всередині підпапки src-папки API. Але додайте цю підпапку у файл .gitignore. Тепер ви можете зберігати розширення всередині API.

  • плюси:

    1. Ваш редактор здатний вирішити залежності

    2. Перед розгортанням коду ви можете запустити команду build і матимете єдиний дистрибутив

    3. Ви можете легко отримати доступ до інших служб ( /groupsпотрібно знайти користувача за ідентифікатором)

  • мінуси:

    1. Під час розробки вам потрібно скопіювати файли репозиторію всередині цієї папки. Після чого щось змінити, вам доведеться скопіювати ці файли назад і замінити файли сховища оновленими.

Третій підхід:

Всередині зовнішньої спеціальної папки всі розширення є повноцінними автономними API. Ваш основний API просто надасть інформацію про аутентифікацію та може діяти як проксі для перенаправлення вхідних запитів на цільовий API.

  • плюси:

    1. Нові розширення можна легко розробити та протестувати
  • мінуси:

    1. Розгортання буде складним. У вас буде основний API та n API розширень, які починають власний процес і слухають порт.

    2. Система проксі може бути складною. Якщо клієнт вимагає, /usersщоб проксі-сервер повинен знати, яке розширення API прослуховує для цієї кінцевої точки, викликає цей API і пересилає цю відповідь клієнту.

    3. Для захисту API розширень (автентифікацією керує основний API) проксі-сервер повинен поділитися секретом з цими API. Тож API розширення передаватиме вхідні запити лише у тому випадку, якщо ця відповідна таємниця надана від проксі.


Четвертий підхід:

Мікросервіси можуть допомогти. Я взяв посібник звідси https://docs.nestjs.com/microservices/basics

Я міг би мати мікросервіс для управління користувачами, управління групами тощо і споживати ці послуги, створивши невеликий api / шлюз / проксі, який викликає ці мікросервіси.

  • плюси:

    1. Нові розширення можна легко розробити та протестувати

    2. Окремі проблеми

  • мінуси:

    1. Розгортання буде складним. У вас буде основний API і n мікросервісів, які починають свій процес і слухають порт.

    2. Здається, що мені доведеться створити новий інтерфейс шлюзу для кожного клієнта, якщо я хочу його налаштувати. Отже, замість розширення програми, мені доведеться створювати індивідуальний інтерфейс API щоразу. Це не вирішило б проблему.

    3. Для захисту API розширень (автентифікацією керує основний API) проксі-сервер повинен поділитися секретом з цими API. Тож API розширення передаватиме вхідні запити лише у тому випадку, якщо ця відповідна таємниця надана від проксі.


2
це може допомогти github.com/nestjs/nest/isissue/3277
Question3r

Дякуємо за посилання Але я не думаю, що я повинен мати спеціальні розширення в коді. Я перевірю, чи вирішать мікросервіси проблему docs.nestjs.com/microservices/basics
hrp8sfH4xQ4

Я думаю, що ваша проблема пов’язана з авторизацією, а не з відпочинку.
adnanmuttaleb

@ adnanmuttaleb Ви б не хотіли пояснити, чому =?
hrp8sfH4xQ4

Відповіді:


6

До цього існує кілька підходів. Що потрібно зробити, це зрозуміти, який робочий процес найкраще підходить для вашої команди, організації та клієнтів.

Якби це не залежало від мене, я б розглядав можливість використання одного сховища на модуль і використовував менеджер пакунків, як NPM, з приватними або організаційними пакетами, щоб обробити конфігурацію. Потім налаштуйте конвеєри випуску збірки, які підштовхуються до репо-пакету для нових збірок.

Таким чином, все, що вам потрібно, - це основний файл та файл маніфесту пакету за користувальницькою установкою. Ви можете самостійно розробляти та розгортати нові версії, а також можете завантажувати нові версії, коли потрібно на клієнтській стороні.

Для додаткової гладкості ви можете використовувати файл конфігурації для картографування модулів для маршрутів та написання загального сценарію генератора маршруту для виконання більшості завантажувальних програм.

Оскільки пакет може бути будь-яким, перехресні залежності всередині цих пакетів працюватимуть без особливих клопотів. Ви просто повинні бути дисциплінованими, коли справа стосується змін та управління версіями.

Детальніше про приватні пакети читайте тут: Приватні пакети NPM

Зараз приватні реєстри NPM коштують грошей, але якщо це питання, є також кілька інших варіантів. Перегляньте цю статтю щодо деяких альтернативних варіантів - безкоштовних та платних.

Способи мати свій приватний реєстр npm

Тепер, якщо ви хочете згорнути власного менеджера, ви можете написати простий сервер-локатор, який бере файл конфігурації, що містить необхідну інформацію, щоб витягнути код з репо, завантажити його та надавати якийсь метод для отримання екземпляр до нього.

Я написав просту реалізацію посилання для такої системи:

Рамка: локатор служби руху

Приклад перевірки плагінів на паліндроми: приклад плагіну локомоції

Додаток, що використовує рамки для пошуку плагінів: приклад програми локомоції

Ви можете пограти з цим, отримавши його з 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 = requ ("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 тоді і мусимо налаштувати власний реєстр. Друга річ, що приватні npm вже не є безкоштовними. Я сподівався знайти базове технічне рішення. Але +1 за ідею :)
hrp8sfH4xQ4

1
додано еталонну реалізацію рудиментарного рішення для такого роду систем.
Espen

3

Я б пішов на варіант зовнішніх пакетів.

Ви можете структурувати додаток, щоб мати packagesпапку. Я мав би UMD склав збірки зовнішніх пакетів у цій папці, щоб у вашої компільованої машинописи не було проблем із пакунками. Усі пакети повинні матиindex.js файл у кореневій папці кожного пакету.

І ваш додаток може запускати цикл через папку пакунків, використовуючи fsта requireвсі пакункиindex.js в вашу програму.

Тоді знову встановлення залежності - це те, про що потрібно подбати. Я думаю, що файл конфігурації кожного пакету може вирішити і це. Ви можете мати звичайnpm скрипт у головному додатку, щоб встановити всі залежності пакету перед запуском програми.

Таким чином, ви можете просто додати нові пакети у свій додаток, скопіювавши вставлення пакета в папку пакунків та перезавантаживши програму. Ваші компільовані файли машинопису не будуть торкатися, і вам не доведеться використовувати приватні npm для власних пакетів.


Дякуємо за Ваш відповідь. Я думаю, це звучить як рішення @ Espen вже розміщене, ні?
hrp8sfH4xQ4

@ hrp8sfH4xQ4 Так, до кінця. Я додав його, прочитавши ваш коментар щодо не хочу використовувати npm. Вище є рішення, яке ви можете зробити, щоб уникнути приватного облікового запису npm. Більше того, я вважаю, що вам не потрібно додавати пакунки, створені кимось поза вашою організацією. Правильно?
Kalesh Kaladharan

btw. але було б чудово підтримати це теж якось ...
hrp8sfH4xQ4

Якщо вам потрібна опція для додавання сторонніх пакетів, то npmце спосіб зробити це чи будь-який інший менеджер пакунків. У таких випадках мого рішення буде недостатньо.
Калеш Каладхаран

Якщо ви не заперечуєте, я хотів би зачекати, щоб зібрати якомога більше підходів
hrp8sfH4xQ4
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.