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 fa581ded493aa405988203fc69bce69116ab3db0 Author: chaokunyang <[email protected]> AuthorDate: Fri Jun 12 07:46:39 2026 +0000 🔄 synced local 'docs/compiler/' with remote 'docs/compiler/' --- docs/compiler/compiler-guide.md | 58 +++++++++++++-------------- docs/compiler/flatbuffers-idl.md | 13 +++--- docs/compiler/generated-code.md | 86 ++++++++++++++++++++++++++++++++++++++++ docs/compiler/index.md | 15 +++---- docs/compiler/protobuf-idl.md | 27 +++++++------ docs/compiler/schema-idl.md | 10 +++-- 6 files changed, 150 insertions(+), 59 deletions(-) diff --git a/docs/compiler/compiler-guide.md b/docs/compiler/compiler-guide.md index 7204116f14..dbad7568f3 100644 --- a/docs/compiler/compiler-guide.md +++ b/docs/compiler/compiler-guide.md @@ -52,27 +52,27 @@ foryc --scan-generated [OPTIONS] Compile options: -| Option | Description | Default | -| ------------------------------------- | ----------------------------------------------------- | ------------- | -| `--lang` | Comma-separated target languages | `all` | -| `--output`, `-o` | Output directory | `./generated` | -| `-I`, `--proto_path`, `--import_path` | Add directory to import search path (can be repeated) | (none) | -| `--java_out=DST_DIR` | Generate Java code in DST_DIR | (none) | -| `--python_out=DST_DIR` | Generate Python code in DST_DIR | (none) | -| `--cpp_out=DST_DIR` | Generate C++ code in DST_DIR | (none) | -| `--go_out=DST_DIR` | Generate Go code in DST_DIR | (none) | -| `--rust_out=DST_DIR` | Generate Rust code in DST_DIR | (none) | -| `--csharp_out=DST_DIR` | Generate C# code in DST_DIR | (none) | -| `--javascript_out=DST_DIR` | Generate JavaScript/TypeScript code in DST_DIR | (none) | -| `--swift_out=DST_DIR` | Generate Swift code in DST_DIR | (none) | -| `--dart_out=DST_DIR` | Generate Dart code in DST_DIR | (none) | -| `--scala_out=DST_DIR` | Generate Scala 3 code in DST_DIR | (none) | -| `--kotlin_out=DST_DIR` | Generate Kotlin code in DST_DIR | (none) | -| `--go_nested_type_style` | Go nested type naming: `camelcase` or `underscore` | `underscore` | -| `--swift_namespace_style` | Swift namespace style: `enum` or `flatten` | `enum` | -| `--emit-fdl` | Emit translated FDL (for non-FDL inputs) | `false` | -| `--emit-fdl-path` | Write translated FDL to this path (file or directory) | (stdout) | -| `--grpc` | Generate gRPC service companions for Java and Python | `false` | +| Option | Description | Default | +| ------------------------------------- | ------------------------------------------------------ | ------------- | +| `--lang` | Comma-separated target languages | `all` | +| `--output`, `-o` | Output directory | `./generated` | +| `-I`, `--proto_path`, `--import_path` | Add directory to import search path (can be repeated) | (none) | +| `--java_out=DST_DIR` | Generate Java code in DST_DIR | (none) | +| `--python_out=DST_DIR` | Generate Python code in DST_DIR | (none) | +| `--cpp_out=DST_DIR` | Generate C++ code in DST_DIR | (none) | +| `--go_out=DST_DIR` | Generate Go code in DST_DIR | (none) | +| `--rust_out=DST_DIR` | Generate Rust code in DST_DIR | (none) | +| `--csharp_out=DST_DIR` | Generate C# code in DST_DIR | (none) | +| `--javascript_out=DST_DIR` | Generate JavaScript/TypeScript code in DST_DIR | (none) | +| `--swift_out=DST_DIR` | Generate Swift code in DST_DIR | (none) | +| `--dart_out=DST_DIR` | Generate Dart code in DST_DIR | (none) | +| `--scala_out=DST_DIR` | Generate Scala 3 code in DST_DIR | (none) | +| `--kotlin_out=DST_DIR` | Generate Kotlin code in DST_DIR | (none) | +| `--go_nested_type_style` | Go nested type naming: `camelcase` or `underscore` | `underscore` | +| `--swift_namespace_style` | Swift namespace style: `enum` or `flatten` | `enum` | +| `--emit-fdl` | Emit translated FDL (for non-FDL inputs) | `false` | +| `--emit-fdl-path` | Write translated FDL to this path (file or directory) | (stdout) | +| `--grpc` | Generate gRPC service companions for supported outputs | `false` | Schema-level file options are supported for language-specific generation choices. For `go_nested_type_style` and `swift_namespace_style`, the CLI flag overrides @@ -141,23 +141,23 @@ foryc schema.fdl --output ./src/generated foryc user.fdl order.fdl product.fdl --output ./generated ``` -**Compile a simple schema containing service definitions (Java + Python models):** +**Compile a simple schema containing service definitions (Java + Python + Rust models):** ```bash -foryc compiler/examples/service.fdl --java_out=./generated/java --python_out=./generated/python +foryc compiler/examples/service.fdl --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust ``` -**Generate Java and Python gRPC service companions:** +**Generate Java, Python, and Rust gRPC service companions:** ```bash -foryc compiler/examples/service.fdl --java_out=./generated/java --python_out=./generated/python --grpc +foryc compiler/examples/service.fdl --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --grpc ``` The generated gRPC service code uses Fory to serialize request and response -payloads. Java output imports grpc-java APIs and Python output imports `grpc`; -applications that compile or run those generated service files must provide -their own gRPC dependencies. Fory's Java and Python packages do not add a hard -gRPC dependency for this feature. +payloads. Java output imports grpc-java APIs, Python output imports `grpc`, and +Rust output imports `tonic` and `bytes`; 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:** diff --git a/docs/compiler/flatbuffers-idl.md b/docs/compiler/flatbuffers-idl.md index 2744ba6ae7..45e88e10af 100644 --- a/docs/compiler/flatbuffers-idl.md +++ b/docs/compiler/flatbuffers-idl.md @@ -125,8 +125,9 @@ message Container { ### Services FlatBuffers `rpc_service` definitions are translated to Fory services. With -`--grpc`, the compiler emits Java and Python gRPC service companions that use -Fory serialization for request and response payloads. +`--grpc`, the compiler emits gRPC service companions for supported outputs such +as Java, Python, Go, and Rust. These companions use Fory serialization for +request and response payloads. ```fbs rpc_service SearchService { @@ -136,12 +137,12 @@ rpc_service SearchService { ``` ```bash -foryc api.fbs --java_out=./generated/java --python_out=./generated/python --grpc +foryc api.fbs --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --grpc ``` -Generated service code imports grpc APIs, so applications must provide grpc-java -or `grpcio` dependencies when they compile or run those files. Fory packages do -not add gRPC as a hard dependency. +Generated service code imports grpc APIs, so applications must provide grpc-java, +`grpcio`, grpc-go, or Rust `tonic` and `bytes` dependencies when they compile or +run those files. Fory packages do not add gRPC as a hard dependency. ### Defaults and Metadata diff --git a/docs/compiler/generated-code.md b/docs/compiler/generated-code.md index 567b9c57ff..1764c47a14 100644 --- a/docs/compiler/generated-code.md +++ b/docs/compiler/generated-code.md @@ -404,6 +404,11 @@ Rust output is one module file per schema, for example: - `<rust_out>/addressbook.rs` +When `--grpc` is used and the schema contains services, Rust also emits: + +- `<rust_out>/addressbook_service.rs` +- `<rust_out>/addressbook_service_grpc.rs` + ### Type Generation Unions map to Rust enums with `#[fory(id = ...)]` schema case attributes. @@ -516,6 +521,51 @@ let bytes = person.to_bytes()?; let restored = Person::from_bytes(&bytes)?; ``` +### gRPC Service Companions + +When a schema contains services and the compiler is run with `--grpc`, Rust +generation emits a service API module and a tonic binding module. For a schema +module named `addressbook`, those files are `addressbook_service.rs` and +`addressbook_service_grpc.rs`. + +The service API module contains the async trait and gRPC path constants: + +```rust +#[::tonic::async_trait] +pub trait AddressBookService: ::std::marker::Send + ::std::marker::Sync + 'static { + async fn lookup( + &self, + request: ::tonic::Request<crate::addressbook::Person>, + ) -> ::std::result::Result< + ::tonic::Response<crate::addressbook::AddressBook>, + ::tonic::Status, + >; +} + +pub const ADDRESS_BOOK_SERVICE_SERVICE_NAME: &str = "addressbook.AddressBookService"; +pub const ADDRESS_BOOK_SERVICE_LOOKUP_PATH: &str = "/addressbook.AddressBookService/Lookup"; +``` + +The tonic binding module contains Fory-backed codecs, payload implementations, +and client/server wrappers. It serializes each request or response with the +generated model type's `to_bytes` and `from_bytes` helpers: + +```rust +impl codec::ForyGrpcPayload for crate::addressbook::Person { + fn encode_fory_payload(&self) -> ::std::result::Result<::std::vec::Vec<u8>, ::fory::Error> { + self.to_bytes() + } + + fn decode_fory_payload(payload: &[u8]) -> ::std::result::Result<Self, ::fory::Error> { + Self::from_bytes(payload) + } +} +``` + +Applications compiling the generated Rust service files must provide `tonic` and +`bytes` dependencies; Fory's Rust crate does not add those gRPC dependencies as +hard dependencies. + ## C++ ### Output Layout @@ -776,6 +826,42 @@ if err := restored.FromBytes(data); err != nil { } ``` +### gRPC Service Companions + +When a schema contains services and the compiler is run with `--grpc`, Go +generation emits one `<module>_grpc.go` file next to the model file. The +companion contains grpc-go client and server interfaces plus a Fory-backed +`CodecV2`. + +```go +type AddressBookServiceClient interface { + Lookup(ctx context.Context, in *Person, opts ...grpc.CallOption) (*AddressBook, error) +} + +func NewAddressBookServiceClient(cc grpc.ClientConnInterface) AddressBookServiceClient { ... } + +type CodecV2 struct{} +``` + +The generated codec uses the same package-level thread-safe Fory runtime as the +generated `ToBytes` and `FromBytes` helpers. Applications should pass +`CodecV2{}` to grpc-go server options, and generated clients force the same +codec on each call: + +```go +server := grpc.NewServer(grpc.ForceServerCodecV2(addressbook.CodecV2{})) +addressbook.RegisterAddressBookServiceServer(server, service) + +client := addressbook.NewAddressBookServiceClient(conn) +``` + +Go method names are exported as PascalCase identifiers, while the gRPC method +path keeps the exact service and method names from the schema. Regenerate both +peers after changing service or method names. + +Applications compiling these files must provide grpc-go dependencies; Fory Go +packages do not add gRPC as a hard dependency. + ## C\# ### Output Layout diff --git a/docs/compiler/index.md b/docs/compiler/index.md index be9990e012..0bcc5ba6fe 100644 --- a/docs/compiler/index.md +++ b/docs/compiler/index.md @@ -23,9 +23,9 @@ 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 and Python, the compiler can generate gRPC -service companions that use Fory serialization for request and response -payloads. +describe RPC services; for Java, Python, Go, and Rust, the compiler can +generate gRPC service companions that use Fory serialization for request and +response payloads. ## Example Schema @@ -88,15 +88,16 @@ service AnimalService { } ``` -Generate Java and Python models plus gRPC service companions with: +Generate Java, Python, and Rust models plus gRPC service companions with: ```bash -foryc animals.fdl --java_out=./generated/java --python_out=./generated/python --grpc +foryc animals.fdl --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --grpc ``` The generated service code uses normal gRPC APIs, but request and response -objects are serialized with Fory. Applications provide their own grpc-java or -`grpcio` dependencies; Fory packages do not add gRPC as a hard dependency. +objects are serialized with Fory. Applications provide their own grpc-java, +`grpcio`, grpc-go, or Rust `tonic` and `bytes` dependencies; Fory packages do +not add gRPC as a hard dependency. ## Why Fory IDL? diff --git a/docs/compiler/protobuf-idl.md b/docs/compiler/protobuf-idl.md index a683f8cd23..66e0e4bc1e 100644 --- a/docs/compiler/protobuf-idl.md +++ b/docs/compiler/protobuf-idl.md @@ -49,13 +49,13 @@ how protobuf concepts map to Fory, and how to use protobuf-only Fory extension o | Circular refs | Not supported | Supported | | Unknown fields | Preserved | Not preserved | | Generated types | Protobuf-specific model types | Native language constructs | -| gRPC ecosystem | Native | Java/Python service codegen | +| gRPC ecosystem | Native | Java/Python/Go/Rust service codegen | -Fory can generate Java and Python 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 the mature/default -choice. +Fory can generate Java, Python, Go, and Rust 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 +the mature/default choice. ## Why Use Apache Fory @@ -311,17 +311,18 @@ modifiers (and optional `ref(weak=true)` where needed). Replace protobuf generation steps with the Fory compiler invocation for target languages. -For Java and Python services, add `--grpc` to emit gRPC companion code: +For supported service outputs, add `--grpc` to emit gRPC companion code: ```bash -foryc api.proto --java_out=./generated/java --python_out=./generated/python --grpc +foryc api.proto --java_out=./generated/java --python_out=./generated/python --rust_out=./generated/rust --grpc ``` -Generated Java service files compile against grpc-java, and generated Python -service modules import `grpc`. 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 response types are not part of normal protobuf RPC +Generated Java service files compile against grpc-java, generated Python service +modules import `grpc`, and generated Rust service files import `tonic` and +`bytes`. 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 +response types are not part of normal protobuf RPC syntax. ### Step 5: Run Compatibility Checks diff --git a/docs/compiler/schema-idl.md b/docs/compiler/schema-idl.md index c3d951b690..c59bbe4c6b 100644 --- a/docs/compiler/schema-idl.md +++ b/docs/compiler/schema-idl.md @@ -907,7 +907,8 @@ 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 Java or Python. +is generated only when the compiler is run with `--grpc` for supported language +outputs such as Java, Python, Go, and Rust. ```protobuf message GetPetRequest [id=200] { @@ -947,9 +948,10 @@ service PetDirectory { - Enum, primitive, collection, map, and array types are not valid direct RPC request or response types. Wrap those values in a message when they are part of a service contract. -- The generated Java and Python gRPC companions use Fory serialization for each - RPC payload. Applications that compile or run those companions provide their - own grpc-java or `grpcio` dependency. +- The generated gRPC companions use Fory serialization for each RPC payload. + Applications that compile or run those companions provide their own gRPC + dependency, such as grpc-java, `grpcio`, grpc-go, or Rust `tonic` and + `bytes`. **Grammar:** --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
