Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
185 changes: 185 additions & 0 deletions blog/2026-06-25-fory_1_3_0_release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---
slug: fory_1_3_0_release
title: Fory v1.3.0 Released
authors: [chaokunyang]
tags: [fory, java, kotlin, scala, android, python, rust, c++, go, c#, swift, dart, compiler]
---

The Apache Fory team is pleased to announce the 1.3.0 release. This release includes [8 PRs](https://github.com/apache/fory/compare/v1.2.0...v1.3.0) from 3 distinct contributors and continues to improve the cross-language runtime across supported languages. See the [Install](https://fory.apache.org/docs/start/install) page to get the libraries for your platform.

## Highlights

* Python gRPC code generation now defaults to the `grpc.aio` AsyncIO API, while synchronous `grpcio` output remains available through `--grpc-python-mode=sync`.
* Dart joins the generated gRPC service surface: `foryc --dart_out=... --grpc` now emits `package:grpc` clients, service bases, method descriptors, and Fory-backed payload serialization.
* Compiler gRPC documentation was refined across languages, including clearer guidance for generated service dependencies and transport behavior.
* Runtime hardening continued with remote schema metadata limits and Java aligned-varint/type-checker fixes.

## Python Async gRPC Mode

Python gRPC generation now targets AsyncIO by default. Generated companions use
`grpc.aio`: servicer bases expose `async def` methods, stubs are used with
`grpc.aio.Channel` instances, and streaming RPCs use async iterables. This keeps
the generated code aligned with modern Python async services while preserving
the same Fory-backed request and response encoding used by the existing gRPC
support.

Generate the default async companion with:

```bash
foryc service.fdl --python_out=./generated/python --grpc
```

For a simple unary service, the generated async server shape is:

```python
import asyncio

import grpc.aio

import demo_greeter
import demo_greeter_grpc


class Greeter(demo_greeter_grpc.GreeterServicer):
async def say_hello(self, request, context):
return demo_greeter.HelloReply(reply=f"Hello, {request.name}")


async def serve():
server = grpc.aio.server()
demo_greeter_grpc.add_servicer(Greeter(), server)
server.add_insecure_port("[::]:50051")
await server.start()
await server.wait_for_termination()


asyncio.run(serve())
```

Clients use a `grpc.aio` channel and await generated stub methods:

```python
import grpc
import grpc.aio

import demo_greeter
import demo_greeter_grpc


credentials = grpc.ssl_channel_credentials()
async with grpc.aio.secure_channel("api.example.com:443", credentials) as channel:
stub = demo_greeter_grpc.GreeterStub(channel)
reply = await stub.say_hello(demo_greeter.HelloRequest(name="Fory"))
```

Existing synchronous applications can still request sync companions explicitly:

```bash
foryc service.fdl --python_out=./generated/python --grpc --grpc-python-mode=sync
```

In sync mode the generated public names and `<module>_grpc.py` filename stay the
same, but applications use `grpc.server(...)`, standard `grpc.Channel`
instances, and regular `def` servicer methods.

## Dart gRPC Code Generation

Fory 1.3.0 adds Dart gRPC service generation for schemas with service
definitions. Service definitions can come from Fory IDL, protobuf IDL, or
FlatBuffers `rpc_service` definitions. The generated code uses normal
grpc-dart APIs for clients, service bases, method descriptors, call options,
deadlines, cancellations, metadata, and status codes, while each request and
response object is serialized with Fory instead of protobuf message bytes.

Add `grpc` and `build_runner` alongside the Fory package in the Dart
application:

```yaml
dependencies:
fory: ^1.3.0
grpc: ^4.0.0

dev_dependencies:
build_runner: ^2.4.0
```

Generate Dart models and the gRPC companion with:

```bash
foryc service.fdl --dart_out=./lib/generated --grpc
dart run build_runner build --delete-conflicting-outputs
```

For a `demo.greeter` package, the generator emits the model file, the
`build_runner` serializer part, and a `<stem>_grpc.dart` companion with
`GreeterServiceBase` and `GreeterClient`. The generated client and service base
install the schema's Fory module automatically on first use, so service
implementations do not need a separate manual registration step for the
generated message types.

A unary Dart server uses grpc-dart's `Server` and the generated service base:

```dart
import 'dart:io';

import 'package:grpc/grpc.dart';
import 'demo/greeter/greeter.dart';
import 'demo/greeter/greeter_grpc.dart';

class GreeterService extends GreeterServiceBase {
@override
Future<HelloReply> sayHello(ServiceCall call, HelloRequest request) async {
return HelloReply()..reply = 'Hello, ${request.name}';
}
}

Future<void> main() async {
final server = Server.create(services: [GreeterService()]);
await server.serve(address: InternetAddress.loopbackIPv4, port: 50051);
}
```

Generated Dart clients use standard `ClientChannel` values and return the
grpc-dart call types:

```dart
import 'package:grpc/grpc.dart';
import 'demo/greeter/greeter.dart';
import 'demo/greeter/greeter_grpc.dart';

final channel = ClientChannel(
'localhost',
port: 50051,
options: const ChannelOptions(credentials: ChannelCredentials.insecure()),
);
final client = GreeterClient(channel);

final reply = await client.sayHello(HelloRequest()..name = 'Fory');
await channel.shutdown();
```

Dart generation covers unary, server-streaming, client-streaming, and
bidirectional streaming RPC shapes following grpc-dart conventions.

## Features

* feat(python): add async grpc mode for python by @chaokunyang in https://github.com/apache/fory/pull/3768
* feat: limit remote schema metadata by @chaokunyang in https://github.com/apache/fory/pull/3770
* feat(compiler): add dart gRPC codegen by @yash-agarwa-l in https://github.com/apache/fory/pull/3723

## Bug Fix

* fix(java): guard aligned varint unsafe read by @chaokunyang in https://github.com/apache/fory/pull/3772
* fix(java): cache accepted type checker classes by @chaokunyang in https://github.com/apache/fory/pull/3773

## Other Improvements

* docs: refine gRPC support guides by @chaokunyang in https://github.com/apache/fory/pull/3767
* docs: add threat model + SECURITY.md/AGENTS.md discoverability by @potiuk in https://github.com/apache/fory/pull/3734
* chore(release): enforce OpenJDK 25 for JVM publishing by @chaokunyang in https://github.com/apache/fory/pull/3775

## New Contributors

* @potiuk made their first contribution in https://github.com/apache/fory/pull/3734

**Full Changelog**: https://github.com/apache/fory/compare/v1.2.0...v1.3.0
32 changes: 16 additions & 16 deletions docs/start/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ Use Maven to add Apache Fory™:
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-core</artifactId>
<version>1.2.0</version>
<version>1.3.0</version>
</dependency>
<!-- Optional row format support -->
<!--
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-format</artifactId>
<version>1.2.0</version>
<version>1.3.0</version>
</dependency>
-->
<!-- SIMD acceleration for array compression (Java 16+) -->
<!--
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-simd</artifactId>
<version>1.2.0</version>
<version>1.3.0</version>
</dependency>
-->
```
Expand All @@ -44,7 +44,7 @@ Scala 2.13 with Maven:
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-scala_2.13</artifactId>
<version>1.2.0</version>
<version>1.3.0</version>
</dependency>
```

Expand All @@ -54,20 +54,20 @@ Scala 3 with Maven:
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-scala_3</artifactId>
<version>1.2.0</version>
<version>1.3.0</version>
</dependency>
```

Scala 2.13 with sbt:

```sbt
libraryDependencies += "org.apache.fory" % "fory-scala_2.13" % "1.2.0"
libraryDependencies += "org.apache.fory" % "fory-scala_2.13" % "1.3.0"
```

Scala 3 with sbt:

```sbt
libraryDependencies += "org.apache.fory" % "fory-scala_3" % "1.2.0"
libraryDependencies += "org.apache.fory" % "fory-scala_3" % "1.3.0"
```

## Kotlin
Expand All @@ -78,23 +78,23 @@ Add Apache Fory™ Kotlin with Maven:
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-kotlin</artifactId>
<version>1.2.0</version>
<version>1.3.0</version>
</dependency>
```

## Python

```bash
python -m pip install --upgrade pip
pip install pyfory==1.2.0
pip install pyfory==1.3.0
```

## Go

Use the full Go module path `github.com/apache/fory/go/fory`:

```bash
go get github.com/apache/fory/go/fory@v1.2.0
go get github.com/apache/fory/go/fory@v1.3.0
```

If your Go proxy has not picked up the new submodule tag yet, retry later or use `GOPROXY=direct` temporarily.
Expand All @@ -103,13 +103,13 @@ If your Go proxy has not picked up the new submodule tag yet, retry later or use

```toml
[dependencies]
fory = "1.2.0"
fory = "1.3.0"
```

Or use `cargo add`:

```bash
cargo add fory@1.2.0
cargo add fory@1.3.0
```

## JavaScript / TypeScript
Expand All @@ -132,7 +132,7 @@ Add Apache Fory™ Dart to `pubspec.yaml`:

```yaml
dependencies:
fory: ^1.2.0
fory: ^1.3.0

dev_dependencies:
build_runner: ^2.4.13
Expand All @@ -149,12 +149,12 @@ dart run build_runner build --delete-conflicting-outputs
Install the `Apache.Fory` NuGet package. It includes both the runtime and the source generator for `[ForyObject]` types.

```bash
dotnet add package Apache.Fory --version 1.2.0
dotnet add package Apache.Fory --version 1.3.0
```

```xml
<ItemGroup>
<PackageReference Include="Apache.Fory" Version="1.2.0" />
<PackageReference Include="Apache.Fory" Version="1.3.0" />
</ItemGroup>
```

Expand All @@ -164,7 +164,7 @@ Add Apache Fory™ from the GitHub repository with Swift Package Manager:

```swift
dependencies: [
.package(url: "https://github.com/apache/fory.git", exact: "1.2.0")
.package(url: "https://github.com/apache/fory.git", exact: "1.3.0")
],
targets: [
.target(
Expand Down
2 changes: 1 addition & 1 deletion docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const config: Config = {
{
docs: {
sidebarCollapsible: true,
lastVersion: '1.2.0',
lastVersion: '1.3.0',
versions: {
current: {
label: 'dev',
Expand Down
Empty file.
Loading
Loading