评估与调整

Sushi SaaS 如何路由请求

了解 middleware 为用户和运营做了什么、为何组织选择保留在 URL 中,以及你可以修改哪些路由决策。

Sushi SaaS middleware 处理请求级上下文,不负责认证或业务授权。它的三项工作——语言路由、请求关联和组织上下文传递——都会产生用户可感知的行为,因此应该由你明确选择。

用户会感受到什么

  • 页面通过 next-intl 进入正确的本地化路由。
  • 两个标签页可停留在两个不同 workspace,因为当前组织由 ?org=<slug> 表达,而非只存于 session。
  • 分享账户链接时,链接本身会显示目标 workspace。

每个响应也包含 x-request-id,运营人员可把客服报告与结构化日志对应起来。API 请求跳过语言协商,但仍获得相同的请求与组织上下文。

实现见 7580470src/middleware.ts

Middleware 实际信任什么

页面请求的组织上下文来自 URL query parameter,调用者自行提供的组织 header 会被移除。API 请求中,共享 client 可以发送 x-organization-slug;若 URL 也提供值,则 URL 优先。

二者都不能直接授权。src/services/authz.ts 仍会证明登录用户属于目标组织,并拒绝多组织用户发起的模糊 API 请求。Middleware 只校验上下文是否适合传递。

只有符合长度与日志安全格式的外部 request ID 才会被接受,否则应用生成新的 UUID。这个 ID 会同时转发给路由并写入响应。

你可以做出的选择

语言路由

如果产品需要带 locale 的页面和语言检测,应保留 next-intl middleware。单语言产品可以移除这条分支,但应同时调整本地化路由、消息目录和测试;只移除一半契约通常会导致重定向与链接互相矛盾。

Workspace 选择

默认 query-string 模式能按标签页独立工作,也容易加到现有账户 URL。/acme/account 这类 path-based tenancy 层级更清晰,但需要修改链接生成、callback、matcher 与上下文解析。只用 session 虽然看似简单,两个标签页却可能覆盖同一个 active organization;只有接受这一行为时才适合。

请求追踪

几乎所有线上产品都应保留关联 ID。如果代理或可观测平台负责 trace ID,可以把可信值映射到日志契约中,或同时保留两者。不要让无限制的外部文本进入日志。

API 上下文

多 workspace 用户的 API 必须显式指定组织,能避免操作悄悄落入上一次活跃的租户。只有 API 确定是单租户时才应简化。

何时在 middleware 添加逻辑

只有必须在路由前运行、并且快速且 edge-compatible 的关注点才放在这里。成员检查、依赖数据库的授权、计费决策和其他业务规则应留在 service。

修改后测试本地化页面、/api 路由、静态资源、request ID 转发、异常上下文和双标签页切换。然后阅读架构与错误契约组织与团队

Sushi SaaS 如何路由请求 · Sushi SaaS