跳到主要内容
版本:0.15

概览

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/None
  • ref:为共享/循环引用启用引用跟踪
  • list:字段为列表/数组(别名:repeated
message Example {
optional string nullable = 1;
ref Node parent = 2;
list<int32> numbers = 3;
}

跨语言兼容

Fory IDL 类型会映射为各语言原生类型:

Fory IDL 类型JavaPythonGoRustC++
int32intpyfory.int32int32i32int32_t
stringStringstrstringStringstd::string
boolbooleanboolboolboolbool

完整映射请参见 类型系统

最佳实践

  1. 使用有意义的 package 名称:将相关类型分组管理
  2. 为性能分配类型 ID:数值 ID 比基于名称的注册更高效
  3. 预留 ID 范围:为后续扩展保留空隙(例如用户 100-199,订单 200-299)
  4. 显式使用 optional:清晰表达可空语义
  5. 共享对象使用 ref:对象可能被多处引用时开启引用跟踪

示例

完整可运行示例见 examples 目录。