wow-view-store 参考
随 Wow 9.2.0 发布
@ahoo-wang/wow-view-store 随 Wow 9.2.0 发布,与 wow-view-engine 一起,同一个 tag、同一个版本号;在此之前不在 npm 上。补丁版本不破坏它的公开面(入口的导出与错误码);次版本可以破坏,它的发布说明逐条列出每个破坏与迁移步骤(版本范围)。以包的 README 与设计文档为准。
WowViewStore 在视图存储上实现视图引擎的 ViewStore 端口:保存的视图与偏好是两个 Wow 聚合,由独立的 wow-view-store-server 提供,或由引入了 wow-view-store-starter 的 Wow 服务提供。
入口
| 导出 | 作用 |
|---|---|
WowViewStore | store 本身:new WowViewStore({ fetcher, permissions? }),交给 new ViewEngine({ store }) |
WowViewStoreOptions | fetcher:由它的拦截器带上租户、所有者与应用;permissions:哪些按钮可用 |
SHARED_OWNER_ID | (shared),共享视图与共享偏好的所有者段 |
WowViewStoreErrorCodes | 视图存储自己的错误码,与 Wow 的并列 |
export interface WowViewStoreOptions {
fetcher: Fetcher;
permissions?: (definitionId: string) => ViewPermissions;
}合同
| 规则 | 行为 |
|---|---|
| 谁在请求 | store 不收租户、用户或应用。由 fetcher 的拦截器填路径里的 {tenantId} 与个人路径的 {ownerId}(fetcher-cosec 的 ResourceAttributionRequestInterceptor,取自令牌),并发送 CoSec-App-Id;不登录的宿主用自己的拦截器填缺省值 |
| 受众 | 路径的所有者段:个人视图在调用者的路径上,共享视图在 owner/(shared) 上。设为共享是在视图所在路径上 share,设为个人是在调用者自己的路径上 claim |
| 写入 | Command-Request-Id 是端口的 requestId,Command-Aggregate-Version 是它的 revision;每次写入等到快照落地,以读回的视图作答 |
| 重试 | 以过期版本或重复请求 id 被拒的写入,先按请求 id 查一次,重试答第一次写下的结果。服务端不对创建去重(id 由它生成);store 重发自己的创建前先问重放路由,只有从别的 store 发出的重试才会再建一个视图 |
| 错误 | 按 Wow 的错误码映射到 CONFLICT、NOT_FOUND、FORBIDDEN、INVALID 与 UNAVAILABLE;只有没回来认得的错误码时才看 HTTP 状态;没有视图存储的服务端是 UNSUPPORTED。错误把服务端的错误码留在 detail.code,服务端答了话的 UNAVAILABLE 带 reachable |
| 列表顺序 | 系统视图、共享视图、个人视图,每种受众按创建先后;每种受众至多 1000 个 |
| 共享看板 | 被共享仪表盘显示着的视图保持共享:收为个人是 INVALID,boards 原样带上那几块看板的标题,由视图引擎用自己的话说出来 |
宿主
示例服务端与补偿服务引入了 wow-view-store-starter,补偿控制台的视图就存在那里。控制台不登录,于是它插入自己的请求拦截器:请求没给租户、所有者与应用时,填上租户 (0)、所有者 (shared) 与它的应用(compensation-dashboard)——它存下的视图与偏好都是共享的,权限里关掉个人视图。引入 starter 的宿主用 wow.view-store.kafka.topic-prefix 给视图存储的 Kafka 主题一个自己的前缀,宿主自己的主题不变。
CoSec 网关规则
服务端不做认证:租户、所有者与应用按请求写的取,所以每个部署都放在 CoSec 网关后面,由网关的路径规则把它们与令牌对上:
| 路径 | 放行条件 |
|---|---|
/view-store/tenant/{tenantId}/owner/{ownerId}/**,…/view/{id}/claim 与 …/view/{id}/share 除外 | {tenantId} 是令牌的租户,且 {ownerId} 是令牌的 sub |
/view-store/tenant/{tenantId}/owner/(shared)/** 的读 | {tenantId} 是令牌的租户 |
/view-store/tenant/{tenantId}/owner/(shared)/** 的写 | 令牌的租户,且具备写共享视图的角色 |
PUT /view-store/tenant/{tenantId}/owner/{ownerId}/view/{id}/claim、…/share | 令牌的租户,{ownerId} 是令牌的 sub,且具备写共享视图的角色 |
设为个人会把共享视图从所有人的列表里拿走,设为共享会把个人视图发布到所有人的列表里,所以个人规则不能单独放行它们:个人规则里排除 …/view/{id}/claim 与 …/view/{id}/share,只由改受众那一条规则决定(否则谁都能先建个人视图再设为共享,发布共享视图)。CoSec-App-Id 由 CoSec 认证,服务端按它隔离应用;宿主按网关校验的同一个角色给出 permissions:createShared 与 changeAudience 需要写共享视图的角色。完整的规则与理由见视图存储的 README。