To implement a gRPC service using the Mutiny API, create a class that implements the service interface. Then, implement the methods defined in the service interface. If you don’t want to implement a service method just throw an java.lang.UnsupportedOperationException from the method body (the exception will be automatically converted to the appropriate gRPC exception). Finally, implement the service and add the @GrpcService annotation:

import io.quarkus.grpc.GrpcService;
import hello.Greeter;
@GrpcService (1)
public class HelloService implements Greeter { (2)
    @Override
    public Uni<HelloReply> sayHello(HelloRequest request) {
        return Uni.createFrom().item(() ->
                HelloReply.newBuilder().setMessage("Hello " + request.getName()).build()
A gRPC service implementation bean must be annotated with the @GrpcService annotation and should not declare any other CDI qualifier. All gRPC services have the jakarta.inject.Singleton scope. Additionally, the request context is always active during a service call.
hello.Greeter is the generated service interface.

To implement a gRPC service using the default gRPC API, create a class that extends the default implementation base. Then, override the methods defined in the service interface. Finally, implement the service and add the @GrpcService annotation:

import io.quarkus.grpc.GrpcService;
@GrpcService
public class HelloService extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
        String name = request.getName();
        String message = "Hello " + name;
        responseObserver.onNext(HelloReply.newBuilder().setMessage(message).build());
        responseObserver.onCompleted();

By default, all the methods from a gRPC service run on the event loop. As a consequence, you must not block. If your service logic must block, annotate the method with io.smallrye.common.annotation.Blocking:

@Override
@Blocking
public Uni<HelloReply> sayHelloBlocking(HelloRequest request) {
    // Do something blocking before returning the Uni
service Streaming {
    rpc Source(Empty) returns (stream Item) {} // Returns a stream
    rpc Sink(stream Item) returns (Empty) {}   // Reads a stream
    rpc Pipe(stream Item) returns (stream Item) {}  // Reads a streams and return a streams

Using Mutiny, you can implement these as follows:

import io.quarkus.grpc.GrpcService;
@GrpcService
public class StreamingService implements Streaming {
    @Override
    public Multi<Item> source(Empty request) {
        // Just returns a stream emitting an item every 2ms and stopping after 10 items.
        return Multi.createFrom().ticks().every(Duration.ofMillis(2))
                .select().first(10)
                .map(l -> Item.newBuilder().setValue(Long.toString(l)).build());
    @Override
    public Uni<Empty> sink(Multi<Item> request) {
        // Reads the incoming streams, consume all the items.
        return request
                .map(Item::getValue)
                .map(Long::parseLong)
                .collect().last()
                .map(l -> Empty.newBuilder().build());
    @Override
    public Multi<Item> pipe(Multi<Item> request) {
        // Reads the incoming stream, compute a sum and return the cumulative results
        // in the outbound stream.
        return request
                .map(Item::getValue)
                .map(Long::parseLong)
                .onItem().scan(() -> 0L, Long::sum)
                .onItem().transform(l -> Item.newBuilder().setValue(Long.toString(l)).build());
  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
  rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);

Clients can specify the fully qualified service name to get the health status of a specific service or skip specifying the service name to get the general status of the gRPC server.

For more details, check out the gRPC documentation

Additionally, if Quarkus SmallRye Health is added to the application, a readiness check for the state of the gRPC services will be added to the MicroProfile Health endpoint response, that is /q/health.

Quarkus gRPC Server implements the reflection service. This service allows tools like grpcurl or grpcox to interact with your services.

The reflection service is enabled by default in dev mode. In test or production mode, you need to enable it explicitly by setting quarkus.grpc.server.enable-reflection-service to true.

Do we use separate HTTP server to serve gRPC requests. Set this to false if you want to use new Vert.x gRPC support, which uses existing Vert.x HTTP server.

Environment variable: QUARKUS_GRPC_SERVER_USE_SEPARATE_SERVER