# 创建并运行第一个 BLOGE Graph

## When to use

Java 项目已经选择 BLOGE，需要创建第一个 `.bloge` graph 或等价 Fluent Graph 时使用。如果工作只是一次本地调用，不涉及有意义的依赖、分支、韧性、等待或恢复，应停止并重新判断是否需要编排引擎。

## Inspect first

- 从 Maven 最终生效配置读取 BLOGE 版本，不假定项目使用最新版。
- 找到项目已有的 Operator registry 或 Spring `@BlogeOperator` 组件。
- 确认一个业务输入、一个 Operator 和一个可观察输出。
- 阅读[第 2 章](/zh-CN/v/0.9.8-RC1/02-your-first-graph)和[最小 Graph 资产](/assets/v/0.9.8-RC1/chapters/02-your-first-graph/assets/head-first-bloge-examples/src/main/resources/bloge/ch02/hello-world.bloge)。

## Required inputs

必须获得 graph 名称、输入字段与类型、Operator 合同、timeout 期望和调用方需要观察的输出。不得自行补造业务默认值或 fallback。

## Implementation path

1. 添加一个只有单个命名 node、并显式声明 Operator 类型的 graph。
2. 从 `ctx` 绑定 node 输入，不读取隐藏的全局状态。
3. 按 Operator 合同设置有界 timeout。
4. 沿用项目既有方式注册 Operator。
5. 使用 `GraphContext` 执行，并通过 `GraphResult` 断言结果。
6. 只有真实依赖或转换需要显式呈现时，才添加第二个 node。

最小 DSL 形状：

```bloge
graph helloWorld {
  node echo : EchoOperator {
    input { message = ctx.message }
    timeout = 1s
  }
}
```

## MUST / SHOULD / MAY

- **MUST**：显式声明 graph 输入和 node 依赖。
- **MUST**：使用已经注册的 Operator 类型；只有 node 名称不能执行。
- **MUST**：同时提供一个可观察成功断言和一个失败断言。
- **SHOULD**：业务逻辑放在 Operator，编排形状放在 graph。
- **SHOULD**：沿用目标模块既有的 DSL 或 Fluent 风格。
- **MAY**：把单 node graph 用作学习或集成缝，但不能声称它证明了生产拓扑。

## Failure patterns

- Operator 未绑定：编译或装载失败。注册 Operator 或修正声明类型，不通过关闭校验隐藏错误。
- Context 字段缺失：input binding 无法产生 Operator 输入。修正调用方合同或 mapping。
- Graph 能编译但没有断言：增加检查 node 输出和 graph 终态的测试。

## Validation

先运行能够装载并执行该 graph 的最小测试，再运行目标模块测试。只有仓库合同或共享模块变更要求时才扩大到完整 reactor。分别报告每个范围；`Tests run: 0` 和 skipped 不能作为通过证据。

## Evidence

- [第 2 章](/zh-CN/v/0.9.8-RC1/02-your-first-graph)
- [第 3 章](/zh-CN/v/0.9.8-RC1/03-thinking-in-dependencies)
- [固定版本的 BLOGE Core 源码](https://github.com/xbdotl/bloge/tree/cc38fbe5bb79ccc603888e4307cfe566d4674ffc/bloge-core)
- [章节自有 Graph](/assets/v/0.9.8-RC1/chapters/02-your-first-graph/assets/head-first-bloge-examples/src/main/resources/bloge/ch02/hello-world.bloge)
