gRPC
Basic implementation that currently only supports unary calls. gRPC is an high-performance remote procedure call framework developed by Google that enables efficient communication between distributed systems, particularly in microservices architectures.
wtx
does not provide built-in deserialization or serialization utilities capable of manipulate protobuf files. Instead, users are free to choose any third-party that generates Rust bindings and implements the internal Deserialize
and Serialize
traits.
Due to the lack of an official parser, the definitions of a Service
must be manually typed.
Independent benchmarks are available https://github.com/LesnyRumcajs/grpc_bench.
To use this functionality, it is necessary to activate the grpc
feature.
Client Example
//! gRPC client that uses the structure definitions found in the `wtx_instances::grpc_bindings` //! module. //! //! This snippet requires ~40 dependencies and has an optimized binary size of ~700K. extern crate tokio; extern crate wtx; extern crate wtx_instances; use std::borrow::Cow; use wtx::{ data_transformation::dnsn::QuickProtobuf, grpc::Client, http::{client_framework::ClientFramework, ReqResBuffer, ReqResData}, }; use wtx_instances::grpc_bindings::wtx::{GenericRequest, GenericResponse}; #[tokio::main] async fn main() -> wtx::Result<()> { let mut client = Client::new(ClientFramework::tokio(1).build(), QuickProtobuf); let mut rrb = ReqResBuffer::empty(); rrb.uri.reset(format_args!("http://127.0.0.1:9000"))?; let res = client .send_unary_req( ("wtx", "GenericService", "generic_method"), GenericRequest { generic_request_field0: Cow::Borrowed(b"generic_request_value"), generic_request_field1: 123, }, rrb, ) .await?; let generic_response: GenericResponse = client.des_from_res_bytes(res.rrd.body())?; println!("{:?}", generic_response); Ok(()) }
Server Example
//! gRPC server that uses the structure definitions found in the `wtx_instances::grpc_bindings` //! module. extern crate tokio; extern crate wtx; extern crate wtx_instances; use std::borrow::Cow; use wtx::{ data_transformation::dnsn::QuickProtobuf, grpc::{GrpcManager, GrpcMiddleware}, http::{ server_framework::{post, Router, ServerFrameworkBuilder, State}, ReqResBuffer, StatusCode, }, misc::{simple_seed, Xorshift64}, }; use wtx_instances::grpc_bindings::wtx::{GenericRequest, GenericResponse}; #[tokio::main] async fn main() -> wtx::Result<()> { let router = Router::new( wtx::paths!(("wtx.GenericService/generic_method", post(wtx_generic_service_generic_method))), GrpcMiddleware, )?; ServerFrameworkBuilder::new(router) .with_req_aux(|| QuickProtobuf::default()) .tokio_rustls( (wtx_instances::CERT, wtx_instances::KEY), &wtx_instances::host_from_args(), Xorshift64::from(simple_seed()), |error| eprintln!("{error}"), |_| Ok(()), ) .await } async fn wtx_generic_service_generic_method( state: State<'_, (), GrpcManager<QuickProtobuf>, ReqResBuffer>, ) -> wtx::Result<StatusCode> { let _generic_request: GenericRequest = state.stream_aux.des_from_req_bytes(&state.req.rrd.body)?; state.req.rrd.clear(); state.stream_aux.ser_to_res_bytes( &mut state.req.rrd.body, GenericResponse { generic_response_field0: Cow::Borrowed(b"generic_response_value"), generic_response_field1: 321, }, )?; Ok(StatusCode::Ok) }