Crate axum_tonic

source ·
Expand description
/// A middleware that does nothing, but just passes on the request.
async fn do_nothing_middleware<B>(req: Request<B>, next: Next<B>) -> Result<Response, GrpcStatus> {

/// A middleware that cancels the request with a grpc status-code
async fn cancel_request_middleware<B>(_req: Request<B>, _next: Next<B>) -> Result<Response, GrpcStatus> {

async fn main() {

    // Spawn the Server
    tokio::task::spawn(async move {
        // The first grpc-service has middleware that accepts the request.
        let grpc_router1 = Router::new()

        // The second grpc-service instead cancels the request
        let grpc_router2 = Router::new()

        // Merge both routers into one.
        let grpc_router = grpc_router1.merge(grpc_router2);

        // This is the normal rest-router, to which all normal requests are routed
        let rest_router = Router::new()
            .nest("/", Router::new().route("/123", get(|| async move {})))
            .route("/", get(|| async move {}));

        // Combine both services into one
        let service = RestGrpcService::new(rest_router, grpc_router);

        // And serve at


    // Connect to the server with a grpc-client
    let channel = Channel::from_static("")

    let mut client1 = Test1Client::new(channel.clone());
    let mut client2 = Test2Client::new(channel);

    // The first request will succeed
    client1.test1(Test1Request {}).await.unwrap();

    // While the second one gives a grpc Status::Canceled code.
        client2.test2(Test2Request {}).await.unwrap_err().code(),


A simple wrapper around a tonic::Status usable in axum middleware.
This service splits all incoming requests either to the rest-service, or to the grpc-service based on the content-type header.


This trait automatically nests the NamedService at the correct path.