Support layers in generated server codes.
- Dominant language
- Rust
- Stars
- 12.5k
- Forks
- 1.3k
- Avg merge
- 4d 7h
- Merged PRs (30d)
- 24
Description
## Feature Request
### Crates
`tonic`, `tonic-build`
### Motivation
Servers generated by `tonic-build` have `with_interceptor` method, so that users can inject some layers before underlying service. However, ` async/await` is unavailable in an interceptor.
Although the document and examples suggest to use `Server::layer` for such demand, there are some limitations.
1. Users cannot choose services to be wrapped.
2. Layers cannot access `tonic::Request` (`http::Request` is available instead) .
### Proposal
Make `tonic-build` to generate `layer` method for each server.
```rust
Server::builder()
.add_service(ServerA::new(service_a).layer(MyLayer))
.add_service(ServerB::new(service_b))
.serve()
.await?
```
```rust
struct MyLayer {
..
}
impl Layer for MyLayer {
type Service = MyService;
..
}
struct MyService {
..
}
impl Service> for MyService
where
S: Service, Response = tonic::Response, Error = tonic::Status>,
..
{
type Response = tonic::Response;
type Error = tonic::Status;
..
}
```
### Alternatives
A workaround is to conduct routing and type conversion (`http::Request/Response` <-> `tonic::Request/Response`) in layers of `Server::layer`. This is redundant since generated servers do routing and type conversion in them.
Contributor guide
Assessment
This issue has not been assessed yet.