跳到主要内容

Apache Fory 1.6.0 正式发布

· 阅读需 6 分钟
杨朝坤
Apache Fory PMC Member

Apache Fory 团队很高兴地宣布 1.6.0 版本正式发布。本次发布包含 23 个 PR。请访问快速开始页面,获取适用于您所用平台的库。

亮点

  • 增强 Fory JSON,新增日期/时间格式注解与 GraalVM 代码生成支持,并进一步提升性能。
  • 新增 C++ gRPC 代码生成支持。
  • 对齐并增强 Rust Row Format 支持。

增强 Fory JSON

Fory 1.6.0 扩展了 Fory JSON 的映射与部署能力,并进一步优化序列化和反序列化路径。新的 JsonFormat 注解在序列化和反序列化两个方向应用 DateTimeFormatter 格式,还可以为带时刻语义的值指定时区。该注解既支持直接的日期/时间字段,也支持一层直接包装,包括集合元素、Optional 值和 Map 值。

import java.time.Instant;
import java.time.LocalDate;
import java.util.List;
import org.apache.fory.json.ForyJson;
import org.apache.fory.json.annotation.JsonFormat;

public final class Schedule {
@JsonFormat(pattern = "dd/MM/uuuu")
public LocalDate day;

@JsonFormat(pattern = "dd/MM/uuuu")
public List<LocalDate> days;

@JsonFormat(pattern = "uuuu-MM-dd HH:mm:ss XXX", timezone = "Asia/Shanghai")
public Instant timestamp;
}

ForyJson json = ForyJson.builder().build();
Schedule schedule = json.fromJson(
"{\"day\":\"02/01/2024\",\"days\":[\"03/01/2024\"],"
+ "\"timestamp\":\"2024-01-02 11:04:05 +08:00\"}",
Schedule.class);
String encoded = json.toJson(schedule);

Fory JSON 现在还支持在 GraalVM Native Image 中使用生成的 codec。使用 JsonType 标注可达模型;若要在镜像构建期间为某个完整配置生成 codec,可通过可达的 ForyJsonProvider 暴露该配置。未由 provider 返回的配置仍会使用预先准备好的解释执行 codec,无需应用添加反射配置。

import org.apache.fory.json.ForyJson;
import org.apache.fory.json.annotation.ForyJsonProvider;
import org.apache.fory.json.annotation.JsonType;

@JsonType
public final class User {
public long id;
public String name;
}

@ForyJsonProvider
public final class JsonConfigs {
public JsonConfigs() {}

public ForyJson api() {
return ForyJson.builder().writeNullFields(true).build();
}
}

经过优化的序列化和反序列化路径降低了常见 JSON 工作负载的开销。完整行为与约束请参阅 Fory JSON 注解GraalVM Native Image指南。

C++ gRPC 代码生成

Fory Compiler 现在可以从 Fory IDL、protobuf IDL 或 FlatBuffers IDL 生成同步 C++ gRPC service 配套代码。gRPC C++ 负责传输,生成的 Fory codec 负责序列化请求和响应载荷,因此 service 实现无需手动执行序列化或类型注册。

在 Fory IDL 中定义 service,并将 --grpc 与 C++ 输出选项一起传入:

package demo.greeter;

message HelloRequest {
string name = 1;
}

message HelloReply {
string reply = 1;
}

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
foryc service.fdl --cpp_out=./generated/cpp --grpc

编译器会生成 C++ 模型、service 接口、Fory codec、client stub、server adapter 和路由实现。应用只需实现生成的接口,再向常规 gRPC C++ server 注册对应 adapter:

#include "demo_greeter.service.grpc.h"

class MyGreeter final : public demo::greeter::service::Greeter {
public:
::grpc::Status SayHello(
::grpc::ServerContext* context,
const ::demo::greeter::HelloRequest* request,
::demo::greeter::HelloReply* response) override {
(void)context;
response->set_reply("Hello, " + request->name());
return ::grpc::Status::OK;
}
};

MyGreeter implementation;
demo::greeter::service::grpc::GreeterServiceGrpc service(&implementation);
::grpc::ServerBuilder builder;
builder.AddListeningPort("0.0.0.0:50051", ::grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr<::grpc::Server> server = builder.BuildAndStart();

该能力通过同步 gRPC C++ API 支持一元、客户端流式、服务端流式和双向流式 RPC。依赖、生成文件、客户端用法和构建集成请参阅 C++ gRPC 指南

对齐并增强 Rust Row Format

Rust Row Format 现在与 Java、C++ 和 Python 共享的 Standard Row Format 保持一致。它支持由 Schema 驱动的 struct、array、map、嵌套 row、可空值、时间值和经过检查的借用 view。读取端无需重建完整值,即可直接从编码字节访问指定字段和集合元素。

use fory::{from_row, to_row, Error, ForyRow, RowView};
use std::collections::BTreeMap;

#[derive(ForyRow)]
struct UserProfile {
id: i64,
name: String,
scores: Vec<i32>,
labels: BTreeMap<String, String>,
}

fn main() -> Result<(), Error> {
let bytes = to_row(&UserProfile {
id: 42,
name: "Ada".to_owned(),
scores: vec![98, 100],
labels: BTreeMap::from([("team".to_owned(), "compiler".to_owned())]),
})?;

let row = from_row::<UserProfile>(&bytes)?;
assert_eq!(row.id()?, 42);
assert_eq!(row.name()?, "Ada");
assert_eq!(row.scores()?.get(1)?, 100);
assert_eq!(row.labels()?.value(0)?, "compiler");
assert_eq!(row.as_bytes(), bytes);
Ok(())
}

生成的字段方法、array 迭代和 map 索引访问都会返回 Result,并在访问时校验所引用的字节。重复编码时,可以使用 to_row_into 复用调用方持有的缓冲区。支持的类型矩阵、二进制布局和跨语言 Schema 要求请参阅 Rust Row Format 指南

新功能

Bug 修复

其他改进

完整变更日志https://github.com/apache/fory/compare/v1.5.0...v1.6.0