CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkus--quarkus-grpc

Quarkus gRPC extension that enables implementing and consuming gRPC services with reactive and imperative programming models.

Pending
Overview
Eval results
Files

service-implementation.mddocs/

Service Implementation

Core functionality for implementing gRPC services with reactive programming support. Services are implemented as CDI beans with automatic lifecycle management and integration with Quarkus's dependency injection system.

Capabilities

@GrpcService Annotation

Qualifies a CDI bean as a gRPC service implementation. The annotated class will be automatically registered as a gRPC service and made available for client connections.

/**
 * Qualifies a gRPC service.
 */
@Qualifier
@Target({ FIELD, PARAMETER, TYPE })
@Retention(RUNTIME)
public @interface GrpcService {
}

Usage Example:

import io.quarkus.grpc.GrpcService;
import io.smallrye.mutiny.Uni;

@GrpcService
public class GreetingService implements MutinyGreetingGrpc.GreetingImplBase {
    
    @Override
    public Uni<HelloReply> sayHello(HelloRequest request) {
        return Uni.createFrom().item(
            HelloReply.newBuilder()
                .setMessage("Hello " + request.getName())
                .build()
        );
    }
    
    @Override
    public Multi<HelloReply> sayHelloStream(HelloRequest request) {
        return Multi.createFrom().items(
            HelloReply.newBuilder().setMessage("Hello").build(),
            HelloReply.newBuilder().setMessage(request.getName()).build()
        );
    }
}

MutinyService Interface

Marker interface used to identify Mutiny-based gRPC service implementations. Services implementing this interface use reactive return types (Uni and Multi) instead of traditional gRPC StreamObserver patterns.

/**
 * Used to mark a Mutiny service interface generated for a gRPC service.
 */
public interface MutinyService {
}

Usage Example:

import io.quarkus.grpc.GrpcService;
import io.quarkus.grpc.MutinyService;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.Multi;

@GrpcService
public class ProductService implements MutinyService {
    
    // Unary call: request -> response
    public Uni<Product> getProduct(ProductRequest request) {
        return productRepository.findById(request.getId())
            .onItem().ifNull().failWith(new StatusRuntimeException(
                Status.NOT_FOUND.withDescription("Product not found")));
    }
    
    // Server streaming: request -> stream of responses
    public Multi<Product> listProducts(ListProductsRequest request) {
        return productRepository.findByCategory(request.getCategory());
    }
    
    // Client streaming: stream of requests -> response
    public Uni<BulkCreateResponse> createProducts(Multi<Product> products) {
        return products
            .onItem().transform(productRepository::save)
            .collect().asList()
            .onItem().transform(savedProducts -> 
                BulkCreateResponse.newBuilder()
                    .setCount(savedProducts.size())
                    .build());
    }
    
    // Bidirectional streaming: stream of requests -> stream of responses
    public Multi<ProcessResult> processProducts(Multi<Product> products) {
        return products
            .onItem().transform(this::processProduct)
            .onItem().transform(result -> 
                ProcessResult.newBuilder()
                    .setStatus(result.isSuccess() ? "SUCCESS" : "FAILED")
                    .build());
    }
}

MutinyGrpc Interface

Marker interface for generated Mutiny gRPC services. This interface is typically implemented by code-generated classes that provide the Mutiny-based service interface.

/**
 * Used to mark a generated Mutiny gRPC service.
 */
public interface MutinyGrpc {
}

MutinyBean Interface

Marker interface for convenient Mutiny beans generated for gRPC services. These beans provide additional convenience methods and integrations.

/**
 * Used to mark a convenient Mutiny bean generated for a gRPC service.
 */
public interface MutinyBean {
}

MutinyStub Interface

Marker interface for generated Mutiny gRPC stubs. These stubs are used internally by the framework for client-side communication.

/**
 * A marker interface that represents a generated Mutiny gRPC stub.
 */
public interface MutinyStub {
}

Error Handling in Services

Services can handle errors using standard Mutiny error handling patterns or by throwing gRPC StatusRuntimeException:

@GrpcService
public class UserService implements MutinyService {
    
    public Uni<User> getUser(GetUserRequest request) {
        return userRepository.findById(request.getId())
            .onItem().ifNull().failWith(() -> 
                new StatusRuntimeException(
                    Status.NOT_FOUND.withDescription("User not found")))
            .onFailure(IllegalArgumentException.class).transform(ex ->
                new StatusRuntimeException(
                    Status.INVALID_ARGUMENT.withDescription(ex.getMessage())));
    }
}

CDI Integration

gRPC services are full CDI beans and support all CDI features:

@GrpcService
@ApplicationScoped
public class OrderService implements MutinyService {
    
    @Inject
    OrderRepository orderRepository;
    
    @Inject
    PaymentService paymentService;
    
    @ConfigProperty(name = "order.tax-rate", defaultValue = "0.1")
    Double taxRate;
    
    public Uni<Order> createOrder(CreateOrderRequest request) {
        return Uni.createFrom().item(request)
            .onItem().transform(this::validateOrder)
            .onItem().transformToUni(orderRepository::save)
            .onItem().transformToUni(order -> 
                paymentService.processPayment(order)
                    .onItem().transform(payment -> order.withPayment(payment)));
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkus--quarkus-grpc

docs

client-usage.md

configuration.md

exception-handling.md

index.md

interceptors.md

reactive-streaming.md

service-implementation.md

tile.json