==== gRPC

The `jooby-grpc` module provides first-class, native support for https://grpc.io/[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.

===== Usage

gRPC strictly requires HTTP/2. Before installing the module, ensure your application is configured to use a supported server with HTTP/2 enabled.

[source, xml, role="primary"]
.Maven
----
<dependency>
  <groupId>io.jooby</groupId>
  <artifactId>jooby-grpc</artifactId>
  <version>${jooby.version}</version>
</dependency>
----

[source, gradle, role="secondary"]
.Gradle
----
implementation 'io.jooby:jooby-grpc:${jooby.version}'
----

[source, java, role="primary"]
.Java
----
import io.jooby.Jooby;
import io.jooby.ServerOptions;
import io.jooby.grpc.GrpcModule;

public class App extends Jooby {
  {
    setServerOptions(new ServerOptions().setHttp2(true)); // <1>

    install(new GrpcModule( // <2>
        new GreeterService()
    ));

    get("/api/health", ctx -> "OK"); // <3>
  }
}
----

[source, kotlin, role="secondary"]
.Kotlin
----
import io.jooby.ServerOptions
import io.jooby.grpc.GrpcModule
import io.jooby.kt.Kooby

class App : Kooby({
  serverOptions = ServerOptions().setHttp2(true) // <1>

  install(GrpcModule( // <2>
      GreeterService()
  ))

  get("/api/health") { "OK" } // <3>
})
----

<1> Enable HTTP/2 on your server.
<2> Install the module and explicitly register your services.
<3> Standard REST routes still work on the exact same port!

===== Dependency Injection

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).

[source, java, role="primary"]
.Java
----
import io.jooby.Jooby;
import io.jooby.di.GuiceModule;
import io.jooby.grpc.GrpcModule;

public class App extends Jooby {
  {
    install(new GuiceModule());

    install(new GrpcModule(
        GreeterService.class // <1>
    ));
  }
}
----

[source, kotlin, role="secondary"]
.Kotlin
----
import io.jooby.di.GuiceModule
import io.jooby.grpc.GrpcModule
import io.jooby.kt.Kooby

class App : Kooby({
  install(GuiceModule())

  install(GrpcModule(
      GreeterService::class.java // <1>
  ))
})
----
<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.

===== Server Reflection

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:

[source, java, role="primary"]
.Java
----
import io.grpc.protobuf.services.ProtoReflectionServiceV1;
import io.jooby.Jooby;
import io.jooby.grpc.GrpcModule;

public class App extends Jooby {
  {
    install(new GrpcModule(
        new GreeterService(),
        ProtoReflectionServiceV1.newInstance() // <1>
    ));
  }
}
----

[source, kotlin, role="secondary"]
.Kotlin
----
import io.grpc.protobuf.services.ProtoReflectionServiceV1
import io.jooby.grpc.GrpcModule
import io.jooby.kt.Kooby

class App : Kooby({
  install(GrpcModule(
      GreeterService(),
      ProtoReflectionServiceV1.newInstance() // <1>
  ))
})
----
<1> Enables the modern `v1` reflection protocol for maximum compatibility with gRPC clients.

===== Routing & Fallbacks

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.
