# protoc-gen-tonic A `protoc` plugin that generates _[Tonic]_ gRPC server and client code using the _[Prost!]_ code generation engine. [Tonic]: https://github.com/hyperium/tonic [Prost!]: https://github.com/tokio-rs/prost When used in projects that use only Rust code, the preferred mechanism for generating gRPC services with _Tonic_ is to use [`tonic-build`] from within a `build.rs` file. However, when working in polyglot environments, it can be advantageous to utilize common tooling in the Protocol Buffers ecosystem. One common tool used for this purpose is _[buf]_, which simplifies the code generation process and includes several useful features, including linting, package management, and breaking change detection. [`tonic-build`]: https://docs.rs/tonic-build [buf]: https://buf.build ## Usage Ensure that `protoc-gen-tonic` has been installed within a directory on your `$PATH`. Then invoke `protoc` from the command line as follows: ```shell protoc --tonic_out=proto/gen -I proto proto/greeter/v1/greeter.proto ``` ### Options This tool supports all the same options from `tonic-build` except for those that are expected to have been completely handled in an earlier `protoc-gen-prost` step. For information on the effects of these settings, see the related documentation from `tonic-build`: * `default_package_filename=`: [default_package_filename](https://docs.rs/prost-build/latest/prost_build/struct.Config.html#method.default_package_filename) * `extern_path==`: [extern_path](https://docs.rs/prost-build/latest/prost_build/struct.Config.html#method.extern_path) * `compile_well_known_types(=)`: [compile_well_known_types](https://docs.rs/prost-build/latest/prost_build/struct.Config.html#method.compile_well_known_types) * `disable_package_emission(=)`: [disable_package_emission](https://docs.rs/tonic-build/latest/tonic_build/struct.Builder.html#method.disable_package_emission) * `server_attribute==`: [server_attribute](https://docs.rs/tonic-build/latest/tonic_build/struct.Builder.html#method.server_attribute) * `server_mod_attribute==`: [server_mod_attribute](https://docs.rs/tonic-build/latest/tonic_build/struct.Builder.html#method.server_mod_attribute) * `client_attribute==`: [client_attribute](https://docs.rs/tonic-build/latest/tonic_build/struct.Builder.html#method.client_attribute) * `client_mod_attribute==`: [client_mod_attribute](https://docs.rs/tonic-build/latest/tonic_build/struct.Builder.html#method.client_mod_attribute) In addition, the following options can also be specified: * `no_server(=)`: Disables generation of the server modules * `no_client(=)`: Disables generation of the client modules * `no_transport(=)`: Disables generation of connect method using `tonic::transport::Channel` * `no_include(=)`: Skips adding an include into the file generated by `protoc-gen-prost`. This behavior may be desired if this plugin is run in a separate `protoc` invocation and you encounter a `Tried to insert into file that doesn't exist` error. A note on parameter values: * ``: All `,`s appearing in the value must be `\` escaped (i.e. `\,`) This is due to the fact that internally, `protoc` joins all passed parameters with a `,` before sending it as a single string to the underlying plugin. * ``: Protobuf paths beginning with `.` will be matched from the global root (prefix matches). All other paths will be matched as suffix matches. * `(=)`: Boolean values may be specified after a parameter, but if not, the value is assumed to be `true` by virtue of having listed the parameter. ### Usage with `protoc` and `protoc-gen-prost` To make it easier to work with the base definitions generated by `prost`, this plugin assumes that it is being run in a chained mode in the same `protoc` invocation as `protoc-gen-prost`. This can be done by specifying multiple plugins in the same `protoc` invocation like so: ```shell protoc -I proto proto/greeter/v1/greeter.proto \ --prost_out=proto/gen \ --tonic_out=proto/gen ``` When running as separate invocations, `protoc` won't be aware of the base definitions that were generated by `protoc-gen-prost`. In this case, using the `no_include` directive is necessary, and you will need to separately include the generated `.tonic.rs` file. ```shell protoc -I proto proto/greeter/v1/greeter.proto \ --prost_out=proto/gen protoc -I proto proto/greeter/v1/greeter.proto \ --tonic_out=proto/gen \ --tonic_opt=no_include ``` ### Usage with _buf_ When used with _buf_, options can be specified in the `buf.gen.yaml` file. `protoc-gen-prost-tonic` should appear as a plugin step after any `protoc-gen-prost` steps. ```yaml version: v1 plugins: - plugin: prost out: gen - plugin: tonic out: gen ``` If you have specified `compile_well_known_types` or `extern_path` on any earlier step, those should also be specified for this step. The `protoc-gen-tonic` plugin is also published on the Buf Schema Registry as a plugin which you can execute remotely, without needing to explicitly install this tool. See the [plugin listing][1] to identify the latest published version for use. The plugin is referenced as follows: [1]: https://buf.build/community/neoeinstein-tonic ```yaml version: v1 plugins: - plugin: buf.build/community/neoeinstein-tonic:v0.3.0 out: gen ``` Pulling all of these together, you can compile a ready-made crate for a gRPC service with types that can be JSON serialized using the following example. Then you can depend on this crate from the binary that will host the server or use the client. ```yaml version: v1 plugins: - plugin: prost out: gen/src opt: - compile_well_known_types - extern_path=.google.protobuf=::pbjson_types - plugin: prost-serde out: gen/src - plugin: tonic out: gen/src opt: - compile_well_known_types - extern_path=.google.protobuf=::pbjson_types - plugin: prost out: gen opt: - gen_crate=Cargo.toml.tpl ```