This is an automated email from the ASF dual-hosted git repository. chaokunyang pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/fory-site.git
commit a91d5845e4a848f2b7473ed2343377079e582a77 Author: chaokunyang <[email protected]> AuthorDate: Sat Jun 13 07:02:23 2026 +0000 🔄 synced local 'docs/compiler/' with remote 'docs/compiler/' --- docs/compiler/compiler-guide.md | 23 +++++++---- docs/compiler/flatbuffers-idl.md | 6 +-- docs/compiler/generated-code.md | 86 ++++++++++++++++++++++++++++++++++++++++ docs/compiler/index.md | 6 +-- docs/compiler/protobuf-idl.md | 27 +++++++------ docs/compiler/schema-idl.md | 2 +- 6 files changed, 122 insertions(+), 28 deletions(-) diff --git a/docs/compiler/compiler-guide.md b/docs/compiler/compiler-guide.md index 683bd3417d..cd1701070c 100644 --- a/docs/compiler/compiler-guide.md +++ b/docs/compiler/compiler-guide.md @@ -141,24 +141,25 @@ foryc schema.fdl --output ./src/generated foryc user.fdl order.fdl product.fdl --output ./generated ``` -**Compile a simple schema containing service definitions (Java + Python + Rust + Kotlin models):** +**Compile a simple schema containing service definitions (Java + Python + Rust + Scala + Kotlin models):** ```bash -foryc compiler/examples/service.fdl --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --kotlin_out=./generated/kotlin +foryc compiler/examples/service.fdl --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --scala_out=./generated/scala --kotlin_out=./generated/kotlin ``` -**Generate Java, Python, Rust, and Kotlin gRPC service companions:** +**Generate Java, Python, Rust, Scala, and Kotlin gRPC service companions:** ```bash -foryc compiler/examples/service.fdl --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --kotlin_out=./generated/kotlin --grpc +foryc compiler/examples/service.fdl --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --scala_out=./generated/scala --kotlin_out=./generated/kotlin --grpc ``` The generated gRPC service code uses Fory to serialize request and response payloads. Java output imports grpc-java APIs, Python output imports `grpc`, and -Rust output imports `tonic` and `bytes`. Kotlin output imports grpc-java and -grpc-kotlin APIs and uses coroutine stubs. Applications that compile or run -those generated service files must provide their own gRPC dependencies. Fory -packages do not add a hard gRPC dependency for this feature. +Rust output imports `tonic` and `bytes`. Scala output imports grpc-java APIs. +Kotlin output imports grpc-java and grpc-kotlin APIs and uses coroutine stubs. +Applications that compile or run those generated service files must provide +their own gRPC dependencies. Fory packages do not add a hard gRPC dependency for +this feature. **Use import search paths:** @@ -194,6 +195,9 @@ foryc schema.fdl --java_out=./gen/java -I proto/ -I common/ # Generate Scala 3 code to a specific directory foryc schema.fdl --scala_out=./src/main/scala +# Generate Scala 3 models and gRPC service companions +foryc service.fdl --scala_out=./src/main/scala --grpc + # Generate Kotlin code to a specific directory foryc schema.fdl --kotlin_out=./src/main/kotlin ``` @@ -415,6 +419,7 @@ generated/ ├── User.scala ├── Status.scala ├── Animal.scala + ├── ExampleServiceGrpc.scala └── ExampleForyModule.scala ``` @@ -425,6 +430,8 @@ generated/ - Enums use Scala 3 `enum` - Unions use Scala 3 ADT `enum` with `@ForyUnion`, `@ForyCase`, and an `Unknown` - Schema module object included +- With `--grpc`, one `<ServiceName>Grpc.scala` service companion is generated + per local service definition ### Kotlin diff --git a/docs/compiler/flatbuffers-idl.md b/docs/compiler/flatbuffers-idl.md index fa29946acb..203a64c405 100644 --- a/docs/compiler/flatbuffers-idl.md +++ b/docs/compiler/flatbuffers-idl.md @@ -126,8 +126,8 @@ message Container { FlatBuffers `rpc_service` definitions are translated to Fory services. With `--grpc`, the compiler emits gRPC service companions for supported outputs such -as Java, Python, Go, Rust, and Kotlin. These companions use Fory serialization for -request and response payloads. +as Java, Python, Go, Rust, Scala, and Kotlin. These companions use Fory +serialization for request and response payloads. ```fbs rpc_service SearchService { @@ -137,7 +137,7 @@ rpc_service SearchService { ``` ```bash -foryc api.fbs --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --kotlin_out=./generated/kotlin --grpc +foryc api.fbs --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --scala_out=./generated/scala --kotlin_out=./generated/kotlin --grpc ``` Generated service code imports grpc APIs, so applications must provide grpc-java, diff --git a/docs/compiler/generated-code.md b/docs/compiler/generated-code.md index d197fb86f0..dfdc403a09 100644 --- a/docs/compiler/generated-code.md +++ b/docs/compiler/generated-code.md @@ -1589,6 +1589,92 @@ object AddressbookForyModule extends org.apache.fory.ForyModule { } ``` +### gRPC Service Companions + +When a schema contains services and the compiler is run with `--grpc`, Scala +generation emits one `<ServiceName>Grpc.scala` companion per local service +definition. The companion lives in the same Scala package as the generated +models and schema module. + +For a service such as: + +```protobuf +service AddressBookService { + rpc Lookup (Person) returns (AddressBook); + rpc Watch (Person) returns (stream AddressBook); + rpc Upload (stream Person) returns (AddressBook); + rpc Chat (stream Person) returns (stream AddressBook); +} +``` + +the generated companion contains: + +- `SERVICE_NAME` and grpc-java method descriptors +- `AddressBookServiceImplBase` for server implementations +- `AddressBookServiceClient` for client calls +- Fory-backed grpc-java marshallers for request and response payloads + +The generated Scala client keeps grpc-java available per method while adding +Scala-friendly convenience methods for the shapes where a direct Scala handle +can preserve the needed lifecycle controls: + +| RPC shape | Scala convenience method | grpc-java-style method | +| ------------------------------------------------------- | ----------------------------------- | ------------------------------------------------ | +| `rpc Lookup (Person) returns (AddressBook)` | `lookup(request): RpcFuture[Resp]` | async observer, blocking, and `ListenableFuture` | +| `rpc Watch (Person) returns (stream AddressBook)` | `watch(request): RpcIterator[Resp]` | async observer and blocking iterator | +| `rpc Upload (stream Person) returns (AddressBook)` | None | request `StreamObserver` | +| `rpc Chat (stream Person) returns (stream AddressBook)` | None | request and response `StreamObserver` | + +Unary client convenience methods return `org.apache.fory.scala.rpc.RpcFuture`: + +```scala +val client = AddressBookServiceGrpc.newClient(channel) +val call = client.lookup(person) +call.asFuture.foreach(handleAddressBook)(scala.concurrent.ExecutionContext.global) +``` + +Server-streaming client convenience methods return +`org.apache.fory.scala.rpc.RpcIterator`: + +```scala +val stream = client.watch(person) +try { + while (stream.hasNext) { + handleAddressBook(stream.next()) + } +} finally { + stream.close() +} +``` + +Close or cancel the `RpcIterator` when the client stops before consuming the +whole stream. The generated adapter cancels the underlying gRPC call so the +server is not left writing a response stream the client no longer reads. + +Client-streaming and bidirectional methods use grpc-java `StreamObserver` APIs: + +```scala +val requestStream = client.upload( + new io.grpc.stub.StreamObserver[AddressBook] { + override def onNext(value: AddressBook): Unit = handleAddressBook(value) + override def onError(t: Throwable): Unit = handleError(t) + override def onCompleted(): Unit = () + } +) +requestStream.onNext(person) +requestStream.onCompleted() +``` + +Server implementations mirror grpc-java. Unary methods can override the direct +request-to-response method generated by Scala, but streaming methods override +observer-based methods and must call `onNext`, `onError`, and `onCompleted` +according to grpc-java lifecycle rules. + +Applications compiling generated Scala gRPC companions must provide grpc-java +dependencies such as `grpc-api`, `grpc-stub`, and a transport like +`grpc-netty-shaded`. The `fory-scala` artifact does not add grpc-java as a hard +dependency. + ## Cross-Language Notes ### Type ID Behavior diff --git a/docs/compiler/index.md b/docs/compiler/index.md index f9fea15b45..e635bcde0b 100644 --- a/docs/compiler/index.md +++ b/docs/compiler/index.md @@ -23,7 +23,7 @@ Fory IDL is a schema definition language for Apache Fory that enables type-safe cross-language serialization. Define your data structures once and generate native data structure code for Java, Python, C++, Go, Rust, JavaScript/TypeScript, C#, Swift, Dart, Scala, and Kotlin. Fory IDL can also -describe RPC services; for Java, Python, Go, Rust, and Kotlin, the compiler can +describe RPC services; for Java, Python, Go, Rust, Scala, and Kotlin, the compiler can generate gRPC service companions that use Fory serialization for request and response payloads. @@ -88,10 +88,10 @@ service AnimalService { } ``` -Generate Java, Python, Rust, and Kotlin models plus gRPC service companions with: +Generate Java, Python, Rust, Scala, and Kotlin models plus gRPC service companions with: ```bash -foryc animals.fdl --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --kotlin_out=./generated/kotlin --grpc +foryc animals.fdl --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --scala_out=./generated/scala --kotlin_out=./generated/kotlin --grpc ``` The generated service code uses normal gRPC APIs, but request and response diff --git a/docs/compiler/protobuf-idl.md b/docs/compiler/protobuf-idl.md index 4ce825e37d..acf7f7f5ad 100644 --- a/docs/compiler/protobuf-idl.md +++ b/docs/compiler/protobuf-idl.md @@ -41,17 +41,17 @@ how protobuf concepts map to Fory, and how to use protobuf-only Fory extension o ## Protobuf vs Fory at a Glance -| Aspect | Protocol Buffers | Fory | -| ------------------ | ----------------------------- | ------------------------------------------ | -| Primary purpose | RPC/message contracts | High-performance object serialization | -| Encoding model | Tag-length-value | Fory binary protocol | -| Reference tracking | Not built-in | First-class (`ref`) | -| Circular refs | Not supported | Supported | -| Unknown fields | Preserved | Not preserved | -| Generated types | Protobuf-specific model types | Native language constructs | -| gRPC ecosystem | Native | Java/Python/Go/Rust/Kotlin service codegen | - -Fory can generate Java, Python, Go, Rust, and Kotlin gRPC service companions with +| Aspect | Protocol Buffers | Fory | +| ------------------ | ----------------------------- | ------------------------------------------------ | +| Primary purpose | RPC/message contracts | High-performance object serialization | +| Encoding model | Tag-length-value | Fory binary protocol | +| Reference tracking | Not built-in | First-class (`ref`) | +| Circular refs | Not supported | Supported | +| Unknown fields | Preserved | Not preserved | +| Generated types | Protobuf-specific model types | Native language constructs | +| gRPC ecosystem | Native | Java/Python/Go/Rust/Scala/Kotlin service codegen | + +Fory can generate Java, Python, Go, Rust, Scala, and Kotlin gRPC service companions with `--grpc`. Those services use normal gRPC transports but serialize request and response payloads with Fory rather than protobuf. For broad gRPC ecosystem tooling, schema reflection, and protobuf-native interceptors, protobuf remains @@ -314,12 +314,13 @@ languages. For supported service outputs, add `--grpc` to emit gRPC companion code: ```bash -foryc api.proto --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --kotlin_out=./generated/kotlin --grpc +foryc api.proto --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --scala_out=./generated/scala --kotlin_out=./generated/kotlin --grpc ``` Generated Java service files compile against grpc-java, generated Python service modules import `grpc`, generated Rust service files import `tonic` and `bytes`, -and generated Kotlin service files compile against grpc-java and grpc-kotlin. +generated Scala service files compile against grpc-java, and generated Kotlin +service files compile against grpc-java and grpc-kotlin. Add those dependencies in your application build; Fory packages do not add gRPC as a hard dependency. Protobuf `oneof` fields are translated to Fory union fields inside request and response messages. Direct union RPC request or diff --git a/docs/compiler/schema-idl.md b/docs/compiler/schema-idl.md index 40f0821088..4fcf7c52f9 100644 --- a/docs/compiler/schema-idl.md +++ b/docs/compiler/schema-idl.md @@ -908,7 +908,7 @@ union_field := ['repeated'] field_type IDENTIFIER '=' INTEGER [field_options] '; Services define RPC method contracts in Fory IDL. They are optional: schemas with services still generate the normal data model types, and gRPC service code is generated only when the compiler is run with `--grpc` for supported language -outputs such as Java, Python, Go, Rust, and Kotlin. +outputs such as Java, Python, Go, Rust, Scala, and Kotlin. ```protobuf message GetPetRequest [id=200] { --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
