grpc / grpc/grpc-rust

Support layers in generated server codes.

Open
#1,565 5 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.