The jooby-grpc module provides first-class, native support for gRPC.
Unlike traditional setups that require spinning up a separate gRPC server on a different port (often forcing a specific transport like Netty), this module embeds the grpc-java engine directly into Jooby.
By using a custom native bridge, it allows you to run strictly-typed gRPC services alongside your standard REST API routes on the exact same port. It bypasses the standard HTTP/1.1 pipeline in favor of a highly optimized, native interceptor tailored for HTTP/2 multiplexing, reactive backpressure, and zero-copy byte framing. It works natively across Undertow, Netty, and Jetty.
gRPC strictly requires HTTP/2. Before installing the module, ensure your application is configured to use a supported server with HTTP/2 enabled.
.
import io.jooby.Jooby;
import io.jooby.ServerOptions;
import io.jooby.grpc.GrpcModule;
{
setServerOptions(new ServerOptions().setHttp2(true)); // (1)
install(new GrpcModule(new GreeterService())); // (2)
}import io.jooby.ServerOptions
import io.jooby.grpc.GrpcModule
import io.jooby.kt.Kooby
{
serverOptions = ServerOptions().setHttp2(true) // (1)
install(GrpcModule(GreeterService())) // (2)
}-
Enable HTTP/2 on your server.
-
Install the module and explicitly register your services.
If your gRPC services require external dependencies (like database repositories), you can register the service classes instead of pre-instantiated objects. The module will automatically provision them using your active Dependency Injection framework (e.g., Guice, Spring).
import io.jooby.Jooby;
import io.jooby.di.GuiceModule;
import io.jooby.grpc.GrpcModule;
{
install(new GuiceModule());
install(new GrpcModule(GreeterService.class)); // (1)
}import io.jooby.di.GuiceModule
import io.jooby.grpc.GrpcModule
import io.jooby.kt.Kooby
{
install(GuiceModule())
install(GrpcModule(GreeterService::class.java)) // (1)
}-
Pass the class references. The DI framework will instantiate them.
|
Warning
|
gRPC services are registered as Singletons. Ensure your service implementations are thread-safe and do not hold request-scoped state in instance variables. Heavy blocking operations will safely run on background workers, protecting the native server’s I/O event loops. |
If you want to use tools like grpcurl or Postman to interact with your services without providing the .proto files, you can easily enable gRPC Server Reflection.
Include the grpc-services dependency in your build, and register the v1 reflection service alongside your own:
import io.grpc.protobuf.services.ProtoReflectionServiceV1;
import io.jooby.Jooby;
import io.jooby.grpc.GrpcModule;
{
install(new GrpcModule(
new GreeterService(),
ProtoReflectionServiceV1.newInstance() // (1)
));
}import io.grpc.protobuf.services.ProtoReflectionServiceV1
import io.jooby.grpc.GrpcModule
import io.jooby.kt.Kooby
{
install(GrpcModule(
GreeterService(),
ProtoReflectionServiceV1.newInstance() // (1)
))
}-
Enables the modern
v1reflection protocol for maximum compatibility with gRPC clients.
The gRPC module intercepts requests natively before they reach Jooby’s standard router.
If a client attempts to call a gRPC method that does not exist, the request gracefully falls through to the standard Jooby router, returning a native 404 Not Found (which gRPC clients will automatically translate to a Status 12 UNIMPLEMENTED).
If you misconfigure your server (e.g., attempting to run gRPC over HTTP/1.1), the fallback route will catch the request and throw an IllegalStateException to help you identify the missing configuration immediately.