feat(grpc): add ServerBuilder, registration, interceptors, and routing - #2789
feat(grpc): add ServerBuilder, registration, interceptors, and routing#2789sauravzg wants to merge 1 commit into
Conversation
f7320bc to
98ab999
Compare
98ab999 to
a682691
Compare
74c4469 to
cbedd8d
Compare
Introduce the server-side handle/router API for building a gRPC `Server` from a fluent builder. - ServerBuilder: fluent construction via `Server::builder()`, with `add_service`, `interceptor`and `build` / `build_with_runtime`. - Service + ServiceExt: `Service` trait for method registration, plus `with_interceptor` to wrap all of a service's methods (InterceptedService). - Interceptors: `Intercept` trait, no-op `Identity`, and `InterceptExt::chain` for composing interceptors into an `InterceptorChain` (first added runs outermost). - Descriptors: `ServiceDescriptor`, `MethodDescriptor`, and `MethodType`. - Routing: `RouterBuilder` maps method paths to `DynHandle`s. - Options: `ServerOptions` currently empty, but a kitchen sink for options.
cbedd8d to
f3ce938
Compare
| /// # Examples | ||
| /// | ||
| /// ```ignore | ||
| /// let server = Server::builder() |
There was a problem hiding this comment.
We have both ServerBuilder::new() and Server::builder()? Why?
|
|
||
| /// The type (cardinality) of a gRPC method. | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| pub enum MethodType { |
There was a problem hiding this comment.
I thought we would hide this from grpc itself and let it treat everything as bidi streaming?
| rx: impl RecvStream + 'static, | ||
| next: &impl Handle, | ||
| ) -> Trailers { | ||
| next.handle(headers, options, tx, rx).await |
There was a problem hiding this comment.
With optimizations on, does this cause literally no overhead?
| /// Creates a new server with the given handler, runtime, and options. | ||
| pub(crate) fn new( |
There was a problem hiding this comment.
Shouldn't we delete new and require the use of the builder?
| } | ||
|
|
||
| /// Returns the server options. | ||
| pub fn options(&self) -> &ServerOptions { |
| use crate::server::service::Service; | ||
|
|
||
| /// A builder for constructing an immutable [`Router`]. | ||
| pub(crate) struct RouterBuilder<I = Identity> { |
There was a problem hiding this comment.
Hmm, why not use a default type for ServerBuilder, too? I assume this is here so that you can impl RouterBuilder instead of needing to impl RouterBuilder<Identity>?
| /// .add_service(my_service) | ||
| /// .build(); | ||
| /// ``` | ||
| pub struct Router<I = Identity> { |
There was a problem hiding this comment.
This one I can't see why there's a default type?
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ```ignore |
There was a problem hiding this comment.
I would prefer if we could avoid ignore for our examples. Especially as we're heavily iterating on things, there's a high likelihood that they will become broken this way. Please use other tags instead like no_run or use leading # to hide things from the rendered documentation.
| use crate::server::SendStream; | ||
| use crate::server::Server; | ||
| use crate::server::Trailers; | ||
| use crate::server::descriptor::{MethodDescriptor, MethodType, ServiceDescriptor}; |
There was a problem hiding this comment.
Please rustfmt to ungroup imports:
rustfmt --edition=2024 --config imports_granularity=Item --config group_imports=StdExternalCrate <files>
or inside the grpc crate, this will get everything:
cargo fmt -- --config imports_granularity=Item --config group_imports=StdExternalCrate
Introduce the server-side handle/router API for building a gRPC
Serverfrom a fluent builder.Server::builder(), withadd_service,interceptorandbuild.Servicetrait for method registration, pluswith_interceptorto wrap all of a service's methods (InterceptedService).Intercepttrait, no-opIdentity, andInterceptExt::chainfor composing interceptors into anInterceptorChain(first added runs outermost).ServiceDescriptor,MethodDescriptor, andMethodType.RouterBuildermaps method paths toDynHandles.ServerOptionscurrently empty, but a kitchen sink for options.