Wow 聚合识别
识别属于生成器行为,不是公开的 AggregateResolver API。仅有带点号的 operationId 不够。下表反映当前实现,包括 requestBody 组件引用和 response 引用别名链。
识别矩阵
| 输入 | 命中条件 | 缺失/形状错误 |
|---|---|---|
| 根 tags | tag 精确形如 context.aggregate,两段均非空 | 仅有 operation tags 不会建立聚合候选 |
| 命令 operationId | 恰好三段点号分隔,末段为命令名 | 缺失/段数错误跳过;排除 wow.command.send |
| 命令响应 | responses['200'].$ref 直接或经 response 组件别名链到 #/components/responses/wow.CommandOk | 内联等价响应或仅有 201 不识别为命令;循环引用抛错 |
| 命令请求体 | 内联 RequestBody 或已解析的组件 requestBody,其 application/json schema $ref 指向可解析模型 | 缺失/JSON schema 非引用会跳过 |
| 状态操作 | operationId 后缀 .snapshot_state.single,200 application/json schema 为引用 | 无状态则从最终聚合集合排除 |
| 字段操作 | operationId 后缀 .snapshot.count,请求体包含 x-wow-query-fields: { $ref: ... },或 JSON condition schema 的 properties.field 引用 | 无字段则排除;预期形状错误可能抛错 |
| 操作 tags | 必须匹配根 tag,命令/状态/字段才能附着 | 未匹配 tag 忽略 |
| 事件(可选) | .event.list_query;响应数组 items 引用流 schema,其 properties.body.items.anyOf 变体含 name.const 和 body 引用 | 缺失时事件联合为空;错误嵌套形状可能抛错 |
解析器要求同时存在状态和字段,命令与事件可以为空。两段根 tag 确定上下文/聚合;operationId 文本和 tag 并不构成语义一致性校验。info['x-wow-context-alias'] 另行影响普通客户端 basePath。
完整最小输入
保存为 wow.json,使用相同 CLI 命令并传 -i ./wow.json。示例明确使用内联命令 RequestBody、200 CommandOk 引用和两个必需查询操作。结果应在 shop/order 命名空间下包含 commandClient.ts 与 queryClient.ts。
json
{
"openapi": "3.0.3",
"info": {
"title": "Orders",
"version": "1"
},
"tags": [
{
"name": "shop.order"
}
],
"paths": {
"/orders": {
"post": {
"operationId": "shop.order.create",
"tags": ["shop.order"],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/shop.CreateOrder"
}
}
}
},
"responses": {
"200": {
"$ref": "#/components/responses/wow.CommandOk"
}
}
}
},
"/orders/state": {
"post": {
"operationId": "shop.order.snapshot_state.single",
"tags": ["shop.order"],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/shop.OrderState"
}
}
}
}
}
}
},
"/orders/count": {
"post": {
"operationId": "shop.order.snapshot.count",
"tags": ["shop.order"],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/shop.Condition"
}
}
},
"x-wow-query-fields": {
"$ref": "#/components/schemas/shop.OrderFields"
}
},
"responses": {
"200": {
"description": "Count",
"content": {
"application/json": {
"schema": {
"type": "integer"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"shop.CreateOrder": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": ["name"]
},
"shop.OrderState": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"shop.OrderFields": {
"type": "string",
"enum": ["name"]
},
"shop.Condition": {
"type": "object",
"properties": {
"field": {
"$ref": "#/components/schemas/shop.OrderFields"
}
}
}
},
"responses": {
"wow.CommandOk": {
"description": "Accepted"
}
}
}
}实现源码
packages/generator/src/aggregate/aggregateResolver.ts:51
