|
| 1 | +== gRPC |
| 2 | + |
| 3 | +The `jooby-grpc` module provides first-class, native support for https://grpc.io/[gRPC]. |
| 4 | + |
| 5 | +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. |
| 6 | + |
| 7 | +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. |
| 8 | + |
| 9 | +=== Dependency |
| 10 | + |
| 11 | +[source, xml, role="primary"] |
| 12 | +.Maven |
| 13 | +---- |
| 14 | +<dependency> |
| 15 | + <groupId>io.jooby</groupId> |
| 16 | + <artifactId>jooby-grpc</artifactId> |
| 17 | + <version>${jooby.version}</version> |
| 18 | +</dependency> |
| 19 | +---- |
| 20 | + |
| 21 | +[source, gradle, role="secondary"] |
| 22 | +.Gradle |
| 23 | +---- |
| 24 | +implementation 'io.jooby:jooby-grpc:${jooby.version}' |
| 25 | +---- |
| 26 | + |
| 27 | +=== Usage |
| 28 | + |
| 29 | +gRPC strictly requires HTTP/2. Before installing the module, ensure your application is configured to use a supported server with HTTP/2 enabled. |
| 30 | + |
| 31 | +[source, java] |
| 32 | +---- |
| 33 | +import io.jooby.Jooby; |
| 34 | +import io.jooby.ServerOptions; |
| 35 | +import io.jooby.grpc.GrpcModule; |
| 36 | +
|
| 37 | +public class App extends Jooby { |
| 38 | + { |
| 39 | + setServerOptions(new ServerOptions().setHttp2(true)); // <1> |
| 40 | +
|
| 41 | + install(new GrpcModule( // <2> |
| 42 | + new GreeterService() |
| 43 | + )); |
| 44 | +
|
| 45 | + get("/api/health", ctx -> "OK"); // <3> |
| 46 | + } |
| 47 | +
|
| 48 | + public static void main(String[] args) { |
| 49 | + runApp(args, App::new); |
| 50 | + } |
| 51 | +} |
| 52 | +---- |
| 53 | +<1> Enable HTTP/2 on your server. |
| 54 | +<2> Install the module and explicitly register your services. |
| 55 | +<3> Standard REST routes still work on the exact same port! |
| 56 | + |
| 57 | +=== Dependency Injection |
| 58 | + |
| 59 | +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). |
| 60 | + |
| 61 | +[source, java] |
| 62 | +---- |
| 63 | +import io.jooby.Jooby; |
| 64 | +import io.jooby.di.GuiceModule; |
| 65 | +import io.jooby.grpc.GrpcModule; |
| 66 | +
|
| 67 | +public class App extends Jooby { |
| 68 | + { |
| 69 | + install(new GuiceModule()); |
| 70 | +
|
| 71 | + install(new GrpcModule( |
| 72 | + GreeterService.class // <1> |
| 73 | + )); |
| 74 | + } |
| 75 | +} |
| 76 | +---- |
| 77 | +<1> Pass the class references. The DI framework will instantiate them. |
| 78 | + |
| 79 | +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. |
| 80 | + |
| 81 | +=== Server Reflection |
| 82 | + |
| 83 | +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. |
| 84 | + |
| 85 | +Include the `grpc-services` dependency in your build, and register the v1 reflection service alongside your own: |
| 86 | + |
| 87 | +[source, java] |
| 88 | +---- |
| 89 | +import io.grpc.protobuf.services.ProtoReflectionServiceV1; |
| 90 | +
|
| 91 | +public class App extends Jooby { |
| 92 | + { |
| 93 | + install(new GrpcModule( |
| 94 | + new GreeterService(), |
| 95 | + ProtoReflectionServiceV1.newInstance() // <1> |
| 96 | + )); |
| 97 | + } |
| 98 | +} |
| 99 | +---- |
| 100 | +<1> Enables the modern `v1` reflection protocol for maximum compatibility with gRPC clients. |
| 101 | + |
| 102 | +=== Routing & Fallbacks |
| 103 | + |
| 104 | +The gRPC module intercepts requests natively before they reach Jooby's standard router. |
| 105 | + |
| 106 | +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`). |
| 107 | + |
| 108 | +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. |
0 commit comments