【发布时间】:2020-02-25 15:27:47
【问题描述】:
我正在为多个客户创建一个 API。每个客户都使用/users 等核心端点,但有些端点依赖于个人定制。因此,用户 A 可能需要一个特殊的端点 /groups,而其他客户将没有该功能。 顺便说一句,由于这些额外的功能,每个客户也会使用自己的数据库架构。
我个人使用 NestJs(引擎盖下的 Express)。所以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 可以遍历该目录并尝试导入每个模块文件。
-
优点:
- 自定义代码远离核心存储库
-
缺点:
NestJs 使用 Typescript,所以我必须先编译代码。我将如何管理 API 构建和自定义应用程序的构建? (即插即用系统)
自定义扩展非常松散,因为它们只包含一些打字稿文件。由于他们无权访问 API 的 node_modules 目录,我的编辑器会显示错误,因为它无法解析外部包依赖项。
某些扩展程序可能会从另一个扩展程序获取数据。也许组服务需要访问用户服务。这里的事情可能会变得棘手。
第二种方法: 将每个扩展保存在 API 的 src 文件夹的子文件夹中。但是将此子文件夹添加到 .gitignore 文件中。现在您可以将扩展保留在 API 中。
-
优点:
您的编辑器能够解决依赖关系
在部署您的代码之前,您可以运行构建命令,并将拥有一个单一的分发版
您可以轻松访问其他服务(
/groups需要通过id查找用户)
-
缺点:
- 在开发时,您必须将存储库文件复制到该子文件夹中。更改某些内容后,您必须将这些文件复制回来并用更新的文件覆盖您的存储库文件。
第三种方法:
在外部自定义文件夹中,所有扩展都是成熟的独立 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 只会传递传入的请求。
【问题讨论】:
-
感谢您的链接。但我认为我的代码中不应该有自定义扩展。我会检查微服务是否能解决问题docs.nestjs.com/microservices/basics
-
我认为您的问题与授权有关,而不是与休息有关。
-
@adnanmuttaleb 你介意解释一下为什么 = 吗?
标签: javascript rest api express nestjs