Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

gRPC

The gRPC component produces and consumes gRPC with runtime proto resolution. No compile-time code generation is required. The component resolves .proto files at runtime through camel-proto-compiler and prost-reflect. It supports unary, server-streaming, client-streaming, and bidirectional streaming. The mode is auto-detected from the proto method descriptor.

The grpc-example wires a consumer on port 50051 and a timer-driven producer:

    let consumer_route = RouteBuilder::from(&format!(
        "grpc://0.0.0.0:50051/helloworld.Greeter/SayHello?protoFile={}",
        proto_path
    ))
    .set_body(Body::Json(
        serde_json::json!({"message": "Hello from consumer!"}),
    ))
    .to("log:grpc-consumer?showBody=true")
    .build()?;
YAML equivalent
routes:
  - id: grpc-consumer
    from: "grpc://0.0.0.0:50051/helloworld.Greeter/SayHello?protoFile=helloworld.proto&transport=plaintext"
    steps:
      - set_body:
          value:
            message: Hello from consumer!
      - to: "log:grpc-consumer?showBody=true"

The Rust example builds protoFile from CARGO_MANIFEST_DIR. Substitute the real path to your .proto file. The transport=plaintext parameter is required (ADR-0033).

    let producer_route = RouteBuilder::from("timer:grpc-tick?period=3000&repeatCount=3")
        .set_body(Body::Json(serde_json::json!({"name": "World"})))
        .to(format!(
            "grpc://127.0.0.1:50051/helloworld.Greeter/SayHello?protoFile={}",
            proto_path
        ))
        .to("log:grpc-response?showBody=true")
        .build()?;
YAML equivalent
routes:
  - id: grpc-producer
    from: "timer:grpc-tick?period=3000&repeatCount=3"
    steps:
      - set_body:
          value:
            name: World
      - to: "grpc://127.0.0.1:50051/helloworld.Greeter/SayHello?protoFile=helloworld.proto&transport=plaintext"
      - to: "log:grpc-response?showBody=true"

The Rust example builds protoFile from CARGO_MANIFEST_DIR. Substitute the real path to your .proto file.

URI

grpc://<host>:<port>/<package>.<Service>/<Method>?protoFile=<path>&transport=<mode>
ParameterRequiredDefaultDescription
protoFileyesPath to the .proto file for runtime descriptor resolution
transportyesplaintext or tls (ADR-0033)
serverCertPathconsumer (tls)Path to the server TLS certificate
serverKeyPathconsumer (tls)Path to the server TLS key
clientCaPathconsumer (mtls)Path to the client CA certificate for mTLS
clientCertPathproducer (mtls)Path to the client TLS certificate
clientKeyPathproducer (mtls)Path to the client TLS key

Consumer

grpc://0.0.0.0:50051/helloworld.Greeter/SayHello?protoFile=helloworld.proto&transport=plaintext binds an HTTP/2 listener. The Consumer dispatches each inbound gRPC request to the Route. The Exchange body carries the decoded protobuf message as JSON. The Exchange headers carry gRPC metadata.

Multiple GrpcConsumers on the same (host, port) share one HTTP/2 server. Each consumer registers dispatch by URI path. The shared-server registry refuses to mix TLS and plaintext on one listener.

The Consumer supports four RPC modes. It auto-detects the mode from the proto method descriptor. The same Consumer handles unary, server-streaming, client-streaming, and bidirectional calls without configuration changes.

Producer

grpc://127.0.0.1:50051/helloworld.Greeter/SayHello?protoFile=helloworld.proto&transport=plaintext sends the Exchange body as a gRPC call. The Producer holds a lazy pool of connections. It reports endpoint health through RuntimeObservability.

The Producer requires transport=plaintext or transport=tls in the URI (ADR-0033). The legacy tls=true key is rejected: a URI cannot carry a TLS configuration, so tls=true can never be satisfied and fails closed. tls=false still parses and means explicit plaintext. Under tls, the endpoint URL is rewritten to https://. The insecure_skip_verify=true option hard-errors. The component fails closed on an incomplete mTLS identity.

Security

The component enforces security through the unified transport auth kernel (ADR-0061 Rule 1):

  1. Authentication. The interceptor extracts credentials per the route plan's credential sources, authenticates via kernel_authenticate, and installs the typed principal carrier on a fresh Exchange per request in all four RPC modes. AccessMode::Public skips extraction entirely; missing or invalid credentials return Status::unauthenticated (provider-down maps to unavailable).
  2. Authorization. The route's compiled RouteSecurityPlan drives the pre-pipeline dispatch check: a non-Public route requires the kernel carrier on the Exchange or the dispatch is denied before the pipeline runs. Route-level policies evaluate in the pipeline layer against the carrier principal.

Transport setup also fails closed (ADR-0033). Every Endpoint declares transport=plaintext or transport=tls. The component rejects insecure_skip_verify=true, an incomplete mTLS identity, and a TLS/plaintext mismatch on a shared listener.

Streaming

Routes that send streaming responses use GrpcStreamObserver. The observer exposes three methods: on_next, on_error, and on_completed. The route calls these methods to push response messages onto the gRPC stream.

Reference: gRPC crate CONTEXT. Example source: examples/grpc-example.