概览
Fory IDL 是 Apache Fory 的 Schema 定义语言,可实现类型安全的跨语言序列化。 你只需定义一次数据结构,即可为 Java、Python、Go、Rust 和 C++ 生成原生数据结构代码。
示例 Schema
Fory IDL 提供了简单直观的语法来定义跨语言数据结构:
package example;
enum Status {
PENDING = 0;
ACTIVE = 1;
COMPLETED = 2;
}
message User {
string name = 1;
int32 age = 2;
optional string email = 3;
list<string> tags = 4;
}
message Item {
string sku = 1;
int32 quantity = 2;
}
message Order {
ref User customer = 1;
list<Item> items = 2;
Status status = 3;
map<string, int32> metadata = 4;
}
message Dog [id=104] {
string name = 1;
int32 bark_volume = 2;
}
message Cat [id=105] {
string name = 1;
int32 lives = 2;
}
union Animal [id=106] {
Dog dog = 1;
Cat cat = 2;
}
为什么选择 Fory IDL?
Schema 优先开发
在 Fory IDL 中一次定义数据模型,即可在所有语言中生成一致且类型安全的代码。这样可以确保:
- 类型安全:在编译期而不是运行期发现类型错误
- 一致性:各语言使用相同字段名、类型和结构
- 文档性:Schema 本身就是可持续演进的文档
- 可演进性:可在所有实现中受控地进行 Schema 变更
Fory 原生能力
与通用 IDL 不同,Fory IDL 专门为 Fory 序列化设计:
- 引用跟踪:通过
ref一等支持共享引用和循环引用 - 可空字段:通过
optional显式声明可空类型 - 类型注册:内置支持数值 ID 与基于命名空间的注册
- 原生代码生成:生成带 Fory 注解/宏的语言惯用代码
集成开销低
生成代码直接使用各语言原生构造:
- Java:带
@ForyField注解的普通 POJO - Python:带类型提示的 dataclass
- Go:带 struct tag 的结构体
- Rust:带
#[derive(ForyObject)]的结构体 - C++:带
FORY_STRUCT宏的结构体
快速开始
1. 安装编译器
pip install fory-compiler
或从源码安装:
cd compiler
pip install -e .
2. 编写 Schema
创建 example.fdl:
package example;
message Person {
string name = 1;
int32 age = 2;
optional string email = 3;
}
3. 生成代码
# 为所有语言生成
foryc example.fdl --output ./generated
# 为指定语言生成
foryc example.fdl --lang java,python --output ./generated
4. 使用生成代码
Java:
Person person = new Person();
person.setName("Alice");
person.setAge(30);
byte[] data = person.toBytes();
Python:
import pyfory
from example import Person
person = Person(name="Alice", age=30)
data = bytes(person) # 或 `person.to_bytes()`
文档导航
| 文档 | 说明 |
|---|---|
| Fory IDL 语法 | 完整语言语法与文法 |
| 类型系统 | 基础类型、集合类型与类型规则 |
| 编译器指南 | CLI 选项与构建集成 |
| 生成代码 | 各目标语言的输出格式 |
| Protocol Buffers IDL 支持 | 与 protobuf 的对比及迁移指南 |
| FlatBuffers IDL 支持 | FlatBuffers 映射规则与代码生成差异 |
核心概念
字段修饰符
optional:字段可为 null/Noneref:为共享/循环引用启用引用跟踪list:字段为列表/数组(别名:repeated)
message Example {
optional string nullable = 1;
ref Node parent = 2;
list<int32> numbers = 3;
}
跨语言兼容
Fory IDL 类型会映射为各语言原生类型:
| Fory IDL 类型 | Java | Python | Go | Rust | C++ |
|---|---|---|---|---|---|
int32 | int | pyfory.int32 | int32 | i32 | int32_t |
string | String | str | string | String | std::string |
bool | boolean | bool | bool | bool | bool |
完整映射请参见 类型系统。
最佳实践
- 使用有意义的 package 名称:将相关类型分组管理
- 为性能分配类型 ID:数值 ID 比基于名称的注册更高效
- 预留 ID 范围:为后续扩展保留空隙(例如用户 100-199,订单 200-299)
- 显式使用
optional:清晰表达可空语义 - 共享对象使用
ref:对象可能被多处引用时开启引用跟踪
示例
完整可运行示例见 examples 目录。