Я создаю API для нескольких клиентов. Подобные основные конечные точки /users
используются каждым клиентом, но некоторые конечные точки зависят от индивидуальных настроек. Таким образом, может случиться так, что пользователь А хочет иметь специальную конечную точку, /groups
и никакой другой клиент не будет иметь эту функцию. Так же, как sidenote , каждый клиент также использовал бы свою собственную схему базы данных из-за этих дополнительных функций.
Я лично использую NestJs (экспресс под капотом). Таким образом, в app.module
настоящее время регистрируются все мои основные модули (со своими конечными точками и т. Д.)
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module'; // core module
@Module({
imports: [UsersModule]
})
export class AppModule {}
Я думаю, что эта проблема не связана с NestJ, так как бы вы справились с этим в теории?
Мне в основном нужна инфраструктура, способная обеспечить базовую систему. Больше нет конечных точек ядра, потому что каждое расширение уникально, и возможны множественные /users
реализации. При разработке новой функции основное приложение не должно касаться. Расширения должны интегрироваться сами или интегрироваться при запуске. Базовая система поставляется без конечных точек, но будет расширена из этих внешних файлов.
Некоторые идеи приходят мне в голову
Первый подход:
Каждое расширение представляет новый репозиторий. Определите путь к пользовательской внешней папке, содержащей все проекты расширений. Этот пользовательский каталог будет содержать папку groups
сgroups.module
import { Module } from '@nestjs/common';
import { GroupsController } from './groups.controller';
@Module({
controllers: [GroupsController],
})
export class GroupsModule {}
Мой API мог бы пройти через этот каталог и попытаться импортировать каждый файл модуля.
плюсы:
- Пользовательский код хранится вдали от основного хранилища.
минусы:
NestJs использует Typescript, поэтому я должен сначала скомпилировать код. Как бы я управлял сборкой API и сборками из пользовательских приложений? (Подключи и играй система)
Пользовательские расширения очень свободны, потому что они просто содержат некоторые машинописные файлы. Из-за того, что они не имеют доступа к каталогу API node_modules, мой редактор покажет мне ошибки, потому что он не может разрешить внешние зависимости пакета.
Некоторые расширения могут получать данные из другого расширения. Возможно, службе групп необходимо получить доступ к службе пользователей. Здесь может быть сложно.
Второй подход. Храните каждое расширение в подпапке папки src API. Но добавьте эту подпапку в файл .gitignore. Теперь вы можете хранить свои расширения внутри API.
плюсы:
Ваш редактор может разрешить зависимости
Перед развертыванием вашего кода вы можете запустить команду сборки и будет иметь один дистрибутив
Вы можете легко получить доступ к другим услугам (
/groups
необходимо найти пользователя по идентификатору)
минусы:
- При разработке вы должны скопировать файлы репозитория в эту подпапку. После изменения чего-либо вы должны скопировать эти файлы обратно и переопределить файлы репозитория обновленными.
Третий подход:
Внутри внешней пользовательской папки все расширения являются полноценными автономными API. Ваш основной API просто обеспечит аутентификацию и может выступать в качестве прокси для перенаправления входящих запросов в целевой API.
плюсы:
- Новые расширения могут быть легко разработаны и протестированы
минусы:
Развертывание будет сложно. У вас будет основной API и n расширений API, запускающих собственный процесс и прослушивающих порт.
Система прокси может быть хитрой. Если клиент запрашивает,
/users
прокси-сервер должен знать, какое расширение API прослушивает эту конечную точку, вызывает этот API и пересылает этот ответ обратно клиенту.Чтобы защитить API расширений (аутентификация обрабатывается основным API), прокси должен делиться секретом с этими API. Таким образом, API расширения будет передавать входящие запросы, только если соответствующий секретный ключ предоставлен прокси-сервером.
Четвертый подход:
Микросервисы могут помочь. Я взял руководство отсюда https://docs.nestjs.com/microservices/basics
Я мог бы иметь микросервис для управления пользователями, управления группами и т. Д. И использовать эти сервисы, создав небольшой API / шлюз / прокси, который вызывает эти микросервисы.
плюсы:
Новые расширения могут быть легко разработаны и протестированы
Отдельные проблемы
минусы:
Развертывание будет сложно. У вас будет основной API и n микросервисов, запускающих собственный процесс и прослушивающих порт.
Похоже, мне нужно было бы создать новый API-интерфейс шлюза для каждого клиента, если я хочу настроить его. Поэтому вместо расширения приложения мне придется каждый раз создавать настраиваемый API-интерфейс. Это не решило бы проблему.
Чтобы защитить API расширений (аутентификация обрабатывается основным API), прокси должен делиться секретом с этими API. Таким образом, API расширения будет передавать входящие запросы, только если соответствующий секретный ключ предоставлен прокси-сервером.
Ответы:
Есть несколько подходов к этому. Что вам нужно сделать, это выяснить, какой рабочий процесс лучше всего подходит для вашей команды, организации и клиентов.
Если бы это зависело от меня, я бы подумал об использовании одного репозитория на модуль и использовании менеджера пакетов, такого как NPM, с частными или организационными пакетами для обработки конфигурации. Затем настройте конвейеры выпуска сборки, которые будут распространяться на репозиторий в новых сборках.
Таким образом, все, что вам нужно, это основной файл и файл манифеста пакета для каждой пользовательской установки. Вы можете самостоятельно разрабатывать и развертывать новые версии, а также загружать новые версии в случае необходимости на стороне клиента.
Для большей плавности вы можете использовать файл конфигурации для сопоставления модулей с маршрутами и написать универсальный скрипт генератора маршрутов для выполнения большей части начальной загрузки.
Поскольку пакет может быть чем угодно, перекрестные зависимости внутри пакетов будут работать без особых хлопот. Вам просто нужно быть дисциплинированным, когда дело доходит до изменений и управления версиями.
Узнайте больше о частных пакетах здесь: Private Packages NPM
Сейчас частные реестры NPM стоят денег, но если это проблема, есть и несколько других вариантов. Пожалуйста, просмотрите эту статью для некоторых альтернатив - бесплатных и платных.
Способы иметь ваш личный реестр npm
Теперь, если вы хотите запустить свой собственный менеджер, вы можете написать простой локатор службы, который принимает файл конфигурации, содержащий необходимую информацию, чтобы извлечь код из репозитория, загрузить его, а затем предоставить какой-то метод для извлечения пример этому.
Я написал простую справочную реализацию для такой системы:
Фреймворк: локомоция, сервис локатор
Пример плагина для проверки палиндромов: пример плагина locomotion
Приложение, использующее инфраструктуру для поиска плагинов: пример приложения locomotion
Вы можете играть с этим, загрузив ее с НПМ помощью
npm install -s locomotion
вам нужно будет указатьplugins.json
файл со следующей схемой:пример:
загрузить его так: const loco = require ("locomotion");
Затем он возвращает обещание, которое разрешит объект локатора службы, который имеет метод локатора, чтобы получить ваши службы:
Обратите внимание, что это просто эталонная реализация, и она недостаточно надежна для серьезных приложений. Тем не менее, шаблон все еще действителен и показывает суть написания такого рода фреймворка.
Теперь это должно быть расширено за счет поддержки конфигурации плагинов, инициализации, проверки ошибок, может быть добавлена поддержка внедрения зависимостей и так далее.
источник
Я бы пошел на внешний вариант пакетов.
Вы можете структурировать свое приложение, чтобы иметь
packages
папку. Я хотел бы иметь скомпилированные сборки UMD внешних пакетов в этой папке, чтобы у вашей скомпилированной машинописи не было проблем с пакетами. Все пакеты должны иметьindex.js
файл в корневой папке каждого пакета.И ваше приложение может запустить цикл через пакеты папок с использованием
fs
иrequire
всех пакетовindex.js
в ваше приложение.Затем вам необходимо позаботиться об установке зависимостей. Я думаю, что файл конфигурации в каждом пакете может решить эту проблему. У вас может быть собственный
npm
скрипт в главном приложении, чтобы установить все зависимости пакета перед запуском приложения.Таким образом, вы можете просто добавить новые пакеты в ваше приложение, скопировав пакет в папку пакетов и перезагрузив приложение. Ваши скомпилированные машинописные файлы не будут затронуты, и вам не нужно будет использовать частный npm для ваших собственных пакетов.
источник
npm
. Выше это решение, которое вы можете сделать, чтобы избежать частной учетной записи npm. Более того, я считаю, что вам не нужно добавлять пакеты, созданные кем-то за пределами вашей организации. Правильно?npm
есть способ сделать это или любой другой менеджер пакетов. В таких случаях моего решения будет недостаточно.