Tôi đang tạo một API cho nhiều khách hàng. Các điểm cuối cốt lõi như /users
được sử dụng bởi mọi khách hàng nhưng một số điểm cuối dựa trên tùy chỉnh riêng lẻ. Vì vậy, có thể người dùng A muốn có một điểm cuối đặc biệt /groups
và sẽ không có khách hàng nào khác có tính năng đó. Cũng giống như một sidenote , mỗi khách hàng cũng sẽ sử dụng lược đồ cơ sở dữ liệu của riêng mình vì các tính năng bổ sung đó.
Cá nhân tôi sử dụng NestJs (Express dưới mui xe). Vì vậy, app.module
hiện tại đăng ký tất cả các mô-đun cốt lõi của tôi (với các điểm cuối riêng của họ, v.v.)
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module'; // core module
@Module({
imports: [UsersModule]
})
export class AppModule {}
Tôi nghĩ vấn đề này không liên quan đến NestJs vậy bạn sẽ xử lý vấn đề đó như thế nào?
Về cơ bản tôi cần một cơ sở hạ tầng có thể cung cấp một hệ thống cơ bản. Không có điểm cuối cốt lõi nữa vì mỗi phần mở rộng là duy nhất và /users
có thể thực hiện nhiều lần . Khi phát triển một tính năng mới, ứng dụng cốt lõi không nên chạm vào. Các tiện ích mở rộng nên tự tích hợp hoặc nên được tích hợp khi khởi động. Hệ thống lõi không có điểm cuối nhưng sẽ được mở rộng từ các tệp bên ngoài đó.
Một số ý tưởng nảy ra trong đầu tôi
Cách tiếp cận đầu tiên:
Mỗi phần mở rộng đại diện cho một kho lưu trữ mới. Xác định đường dẫn đến thư mục bên ngoài tùy chỉnh chứa tất cả các dự án mở rộng đó. Thư mục tùy chỉnh này sẽ chứa một thư mục groups
cógroups.module
import { Module } from '@nestjs/common';
import { GroupsController } from './groups.controller';
@Module({
controllers: [GroupsController],
})
export class GroupsModule {}
API của tôi có thể lặp qua thư mục đó và cố gắng nhập từng tệp mô-đun.
ưu:
- Mã tùy chỉnh được tránh xa kho lưu trữ lõi
Nhược điểm:
NestJs sử dụng Typecript nên tôi phải biên dịch mã trước. Làm cách nào để quản lý bản dựng API và bản dựng từ các ứng dụng tùy chỉnh? (Hệ thống cắm và chạy)
Các phần mở rộng tùy chỉnh rất lỏng lẻo vì chúng chỉ chứa một số tệp bản thảo. Do thực tế họ không có quyền truy cập vào thư mục node_modules của API, trình soạn thảo của tôi sẽ hiển thị cho tôi các lỗi vì nó không thể giải quyết các phụ thuộc gói bên ngoài.
Một số tiện ích mở rộng có thể tìm nạp dữ liệu từ tiện ích mở rộng khác. Có thể dịch vụ nhóm cần truy cập dịch vụ người dùng. Mọi thứ có thể trở nên khó khăn ở đây.
Cách tiếp cận thứ hai: Giữ mỗi phần mở rộng bên trong thư mục con của thư mục src của API. Nhưng thêm thư mục con này vào tệp .gitignore. Bây giờ bạn có thể giữ các tiện ích mở rộng của mình bên trong API.
ưu:
Trình chỉnh sửa của bạn có thể giải quyết các phụ thuộc
Trước khi triển khai mã của bạn, bạn có thể chạy lệnh xây dựng và sẽ có một bản phân phối
Bạn có thể dễ dàng truy cập các dịch vụ khác (
/groups
cần tìm người dùng theo id)
Nhược điểm:
- Khi phát triển, bạn phải sao chép các tệp lưu trữ của mình bên trong thư mục con đó. Sau khi thay đổi một cái gì đó, bạn phải sao chép các tệp này lại và ghi đè lên các tệp lưu trữ của bạn với các tệp được cập nhật.
Cách tiếp cận thứ ba:
Trong một thư mục tùy chỉnh bên ngoài, tất cả các tiện ích mở rộng đều được API hoàn toàn chính thức. API chính của bạn sẽ chỉ cung cấp công cụ xác thực và có thể hoạt động như một proxy để chuyển hướng các yêu cầu đến tới API mục tiêu.
ưu:
- Các tiện ích mở rộng mới có thể được phát triển và thử nghiệm dễ dàng
Nhược điểm:
Triển khai sẽ là khó khăn. Bạn sẽ có một API chính và n API mở rộng bắt đầu quá trình của riêng mình và lắng nghe một cổng.
Hệ thống proxy có thể khó khăn. Nếu máy khách yêu cầu
/users
proxy cần biết API mở rộng nào lắng nghe điểm cuối đó, hãy gọi API đó và chuyển tiếp phản hồi đó cho máy khách.Để bảo vệ các API mở rộng (xác thực được xử lý bởi API chính), proxy cần chia sẻ bí mật với các API đó. Vì vậy, API tiện ích mở rộng sẽ chỉ chuyển các yêu cầu đến nếu bí mật phù hợp đó được cung cấp từ proxy.
Cách tiếp cận thứ tư:
Dịch vụ vi mô có thể giúp đỡ. Tôi đã lấy một hướng dẫn từ đây https://docs.nestjs.com/microservice/basics
Tôi có thể có một dịch vụ siêu nhỏ để quản lý người dùng, quản lý nhóm, v.v. và sử dụng các dịch vụ đó bằng cách tạo một api / gateway / proxy nhỏ gọi các dịch vụ siêu nhỏ đó.
ưu:
Các tiện ích mở rộng mới có thể được phát triển và thử nghiệm dễ dàng
Mối quan tâm riêng biệt
Nhược điểm:
Triển khai sẽ là khó khăn. Bạn sẽ có một API chính và n microservice bắt đầu quá trình của riêng họ và lắng nghe một cổng.
Có vẻ như tôi sẽ phải tạo một api cổng mới cho mỗi khách hàng nếu tôi muốn nó có thể tùy chỉnh. Vì vậy, thay vì mở rộng một ứng dụng, tôi sẽ phải tạo API comsuming tùy chỉnh mỗi lần. Điều đó sẽ không giải quyết vấn đề.
Để bảo vệ các API mở rộng (xác thực được xử lý bởi API chính), proxy cần chia sẻ bí mật với các API đó. Vì vậy, API tiện ích mở rộng sẽ chỉ chuyển các yêu cầu đến nếu bí mật phù hợp đó được cung cấp từ proxy.