跳到主要内容

Next.js 多租户 SaaS

介绍

多租户(Multi-tenant)架构是一种软件架构模式,允许多个客户(租户)共享同一个应用程序实例,同时保持数据的隔离性。这种架构在 SaaS(软件即服务)应用中非常常见,因为它可以有效地利用资源并降低成本。

在本文中,我们将探讨如何使用 Next.js 构建一个多租户 SaaS 应用。我们将从基本概念开始,逐步深入到实际实现,并通过代码示例和实际案例帮助你理解这一架构。

多租户架构的核心概念

租户隔离

在多租户架构中,每个租户的数据和配置需要相互隔离。常见的隔离方式包括:

  • 数据库级别隔离:每个租户拥有独立的数据库。
  • 表级别隔离:所有租户共享同一个数据库,但每个租户的数据存储在不同的表中。
  • 行级别隔离:所有租户共享同一个表,但通过租户 ID 来区分数据。

租户识别

在请求到达时,应用需要识别当前请求属于哪个租户。常见的识别方式包括:

  • 子域名:例如 tenant1.example.com
  • 路径前缀:例如 example.com/tenant1
  • 请求头:例如在请求头中包含租户 ID。

实现多租户 SaaS 应用

1. 设置 Next.js 项目

首先,创建一个新的 Next.js 项目:

bash
npx create-next-app@latest nextjs-multi-tenant-saas
cd nextjs-multi-tenant-saas

2. 配置多租户路由

我们可以通过子域名或路径前缀来识别租户。以下是一个使用路径前缀的示例:

javascript
// pages/[[...slug]].js
import { useRouter } from 'next/router';

export default function TenantPage() {
const router = useRouter();
const { slug } = router.query;
const tenantId = slug?.[0];

return (
<div>
<h1>Welcome to Tenant {tenantId}</h1>
<p>This is the homepage for tenant {tenantId}.</p>
</div>
);
}

在这个示例中,访问 /tenant1 将会显示租户 tenant1 的主页。

3. 数据隔离

为了实现数据隔离,我们可以使用行级别隔离。假设我们有一个 users 表,我们可以通过租户 ID 来区分数据:

javascript
// lib/db.js
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export async function getUsers(tenantId) {
return prisma.user.findMany({
where: {
tenantId,
},
});
}

4. 动态加载租户配置

每个租户可能有不同的配置,例如主题、语言等。我们可以通过动态加载配置来实现这一点:

javascript
// lib/config.js
export async function getTenantConfig(tenantId) {
// 这里可以从数据库或配置文件中加载租户配置
return {
theme: 'light',
language: 'en',
};
}

5. 实际案例

假设我们正在构建一个多租户的任务管理应用。每个租户可以创建和管理自己的任务,而其他租户无法访问这些任务。

javascript
// pages/tasks/[[...slug]].js
import { useRouter } from 'next/router';
import { getTasks } from '../../lib/db';

export default function TasksPage({ tasks }) {
const router = useRouter();
const { slug } = router.query;
const tenantId = slug?.[0];

return (
<div>
<h1>Tasks for Tenant {tenantId}</h1>
<ul>
{tasks.map((task) => (
<li key={task.id}>{task.title}</li>
))}
</ul>
</div>
);
}

export async function getServerSideProps(context) {
const { slug } = context.params;
const tenantId = slug?.[0];
const tasks = await getTasks(tenantId);

return {
props: {
tasks,
},
};
}

在这个示例中,访问 /tenant1/tasks 将会显示租户 tenant1 的任务列表。

总结

通过本文,我们学习了如何使用 Next.js 构建一个多租户 SaaS 应用。我们从基本概念开始,逐步实现了租户识别、数据隔离和动态配置加载。多租户架构是 SaaS 应用的核心,掌握这一架构将帮助你构建更高效、可扩展的应用。

附加资源

练习

  1. 尝试使用子域名来实现租户识别。
  2. 扩展任务管理应用,允许租户创建和删除任务。
  3. 实现一个租户配置页面,允许租户自定义主题和语言。
提示

在实现多租户应用时,务必确保数据隔离的安全性,避免租户之间的数据泄露。