or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/io.quarkus/quarkus-resteasy-reactive@3.15.x

docs

index.md
tile.json

tessl/maven-io-quarkus--quarkus-resteasy-reactive

tessl install tessl/maven-io-quarkus--quarkus-resteasy-reactive@3.15.0

A Jakarta REST implementation utilizing build time processing and Vert.x for high-performance REST endpoints with reactive capabilities in cloud-native environments.

advanced-integration.mddocs/reference/

Advanced Integration

Quarkus REST provides several advanced integration points for framework developers and extension authors. These APIs are primarily used for custom integrations, observability, and low-level framework customization.

Import

import io.quarkus.resteasy.reactive.server.runtime.ResteasyReactiveInitialiser;
import io.quarkus.resteasy.reactive.server.runtime.QuarkusContextProducers;
import io.quarkus.resteasy.reactive.server.runtime.observability.ObservabilityCustomizer;
import org.jboss.resteasy.reactive.server.core.Deployment;
import org.jboss.resteasy.reactive.server.spi.ServerRestHandler;
import org.jboss.resteasy.reactive.server.handlers.ServerResourceMethod;
import org.jboss.resteasy.reactive.server.model.HandlerChainCustomizer;
import org.jboss.resteasy.reactive.server.model.HandlerChainCustomizer.Phase;

Capabilities

ResteasyReactiveInitialiser

Interface for generated static initialization calls during application startup.

/**
 * Interface for generated static init calls
 * Typically used by Quarkus extensions for custom initialization
 */
public interface ResteasyReactiveInitialiser {
    /**
     * Initialize the deployment with custom configuration
     * @param deployment The RESTEasy Reactive deployment
     */
    void init(Deployment deployment);
}

QuarkusContextProducers

CDI producers for injectable REST context objects.

/**
 * CDI producers for @Context-injectable objects
 * Provides standard Jakarta REST context objects as CDI beans
 */
public class QuarkusContextProducers {
    /**
     * Produces HttpServerResponse for request-scoped injection
     * @return Current HTTP server response
     */
    @Produces
    @RequestScoped
    HttpServerResponse httpServerResponse();

    /**
     * Produces Providers for application-scoped injection
     * @return Providers instance for looking up providers
     */
    @Produces
    @ApplicationScoped
    Providers providers();

    /**
     * Produces Closer for request-scoped resource cleanup
     * @return Closer instance for registering closeables
     */
    @Produces
    @RequestScoped
    Closer closer();
}

ObservabilityCustomizer

Handler chain customizer for integrating observability features (metrics, tracing, etc.).

/**
 * HandlerChainCustomizer for observability integration
 * Used by Quarkus extensions to add observability handlers
 */
public class ObservabilityCustomizer implements HandlerChainCustomizer {
    /**
     * Provide handlers for specific phases of request processing
     * @param phase The processing phase
     * @param resourceClass The resource class being processed
     * @param serverResourceMethod The resource method being processed
     * @return List of handlers to add to the chain
     */
    List<ServerRestHandler> handlers(
        Phase phase,
        ResourceClass resourceClass,
        ServerResourceMethod serverResourceMethod
    );
}

Usage Examples

Custom Initialization

Create a custom initialiser for framework-level setup:

import io.quarkus.resteasy.reactive.server.runtime.ResteasyReactiveInitialiser;
import org.jboss.resteasy.reactive.server.core.Deployment;

public class CustomInitialiser implements ResteasyReactiveInitialiser {

    @Override
    public void init(Deployment deployment) {
        // Custom deployment initialization
        System.out.println("Initializing custom REST deployment");

        // Access deployment configuration
        var config = deployment.getApplicationSupplier();

        // Register custom handlers, filters, etc.
        // This is typically done by Quarkus extensions
    }
}

Custom Context Producer

Extend context producers for custom injectable objects:

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;
import jakarta.enterprise.context.RequestScoped;

@ApplicationScoped
public class CustomContextProducers {

    @Produces
    @RequestScoped
    public CustomContext produceCustomContext() {
        // Provide custom context object
        return new CustomContext();
    }
}

Observability Handler

Implement a custom observability handler:

import io.quarkus.resteasy.reactive.server.runtime.observability.ObservabilityCustomizer;
import org.jboss.resteasy.reactive.server.spi.ServerRestHandler;
import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext;

public class CustomObservabilityHandler implements ServerRestHandler {

    @Override
    public void handle(ResteasyReactiveRequestContext requestContext) {
        // Record metrics, start spans, etc.
        long startTime = System.nanoTime();

        try {
            // Process request
            requestContext.resume();
        } finally {
            // Record duration
            long duration = System.nanoTime() - startTime;
            // Report to metrics system
            recordMetric(requestContext.getMethod(), duration);
        }
    }

    private void recordMetric(String method, long duration) {
        // Implementation specific
    }
}

Handler Chain Customization

Create a custom handler chain customizer:

import org.jboss.resteasy.reactive.server.model.HandlerChainCustomizer;
import org.jboss.resteasy.reactive.server.spi.ServerRestHandler;
import java.util.List;

@ApplicationScoped
public class CustomHandlerCustomizer implements HandlerChainCustomizer {

    @Override
    public List<ServerRestHandler> handlers(
        Phase phase,
        ResourceClass resourceClass,
        ServerResourceMethod serverResourceMethod
    ) {
        if (phase == Phase.AFTER_METHOD_INVOKE) {
            // Add custom post-processing handler
            return List.of(new CustomPostProcessingHandler());
        }
        return List.of();
    }
}

Accessing Deployment Information

Use ResteasyReactiveInitialiser to access deployment metadata:

public class DeploymentInspector implements ResteasyReactiveInitialiser {

    @Override
    public void init(Deployment deployment) {
        // Inspect registered resources
        var resources = deployment.getResourceClasses();

        for (var resource : resources) {
            System.out.println("Resource: " + resource.getClassName());

            // Inspect methods
            for (var method : resource.getMethods()) {
                System.out.println("  Method: " + method.getName());
                System.out.println("  Path: " + method.getPath());
                System.out.println("  HTTP Method: " + method.getHttpMethod());
            }
        }
    }
}

Handler Chain Phases

Handlers can be added at different phases of request processing:

public enum Phase {
    BEFORE_METHOD_INVOKE,   // Before resource method execution
    AFTER_METHOD_INVOKE,    // After resource method execution
    RESOLVED,               // After method resolution
    AFTER_MATCH;            // After path matching
}

Phase-Specific Handlers

@ApplicationScoped
public class PhaseAwareCustomizer implements HandlerChainCustomizer {

    @Override
    public List<ServerRestHandler> handlers(
        Phase phase,
        ResourceClass resourceClass,
        ServerResourceMethod serverResourceMethod
    ) {
        return switch (phase) {
            case BEFORE_METHOD_INVOKE -> List.of(new PreInvokeHandler());
            case AFTER_METHOD_INVOKE -> List.of(new PostInvokeHandler());
            case RESOLVED -> List.of(new ResolvedHandler());
            case AFTER_MATCH -> List.of(new MatchHandler());
        };
    }
}

Best Practices

Extension Development

These APIs are primarily for Quarkus extension developers:

// In a Quarkus extension's processor class
@BuildStep
void registerInitialiser(BuildProducer<ResteasyReactiveInitialiserBuildItem> producer) {
    producer.produce(new ResteasyReactiveInitialiserBuildItem(
        CustomInitialiser.class.getName()
    ));
}

Observability Integration

For metrics, tracing, and monitoring:

@ApplicationScoped
public class MetricsCustomizer implements HandlerChainCustomizer {

    @Inject
    MeterRegistry registry;

    @Override
    public List<ServerRestHandler> handlers(
        Phase phase,
        ResourceClass resourceClass,
        ServerResourceMethod serverResourceMethod
    ) {
        if (phase == Phase.BEFORE_METHOD_INVOKE) {
            return List.of(new MetricsHandler(registry, serverResourceMethod));
        }
        return List.of();
    }
}

Performance Considerations

  • Handlers are executed for every request - keep them lightweight
  • Avoid blocking operations in handlers
  • Use phases appropriately to minimize overhead
  • Cache expensive computations at build time when possible

Handler Ordering

Handlers execute in the order they're added:

@Override
public List<ServerRestHandler> handlers(...) {
    return List.of(
        new FirstHandler(),   // Executes first
        new SecondHandler(),  // Executes second
        new ThirdHandler()    // Executes third
    );
}

Integration Examples

Custom Authentication Handler

public class CustomAuthHandler implements ServerRestHandler {

    @Override
    public void handle(ResteasyReactiveRequestContext ctx) {
        String authHeader = ctx.getHeader("Authorization", true);

        if (authHeader == null || !isValid(authHeader)) {
            ctx.setResult(Response.status(401).build());
            return;
        }

        // Continue processing
        ctx.resume();
    }

    private boolean isValid(String authHeader) {
        // Validate token
        return true;
    }
}

Request Logging Handler

public class RequestLoggingHandler implements ServerRestHandler {

    private static final Logger LOG = Logger.getLogger(RequestLoggingHandler.class);

    @Override
    public void handle(ResteasyReactiveRequestContext ctx) {
        LOG.infof("Request: %s %s", ctx.getMethod(), ctx.getPath());

        ctx.resume();

        LOG.infof("Response: %d", ctx.getResponse().getStatus());
    }
}

Caching Handler

public class CachingHandler implements ServerRestHandler {

    private final Cache cache;

    public CachingHandler(Cache cache) {
        this.cache = cache;
    }

    @Override
    public void handle(ResteasyReactiveRequestContext ctx) {
        String cacheKey = ctx.getMethod() + ":" + ctx.getPath();

        var cached = cache.get(cacheKey);
        if (cached != null) {
            ctx.setResult(cached);
            return;
        }

        // Continue and cache result
        ctx.resume();

        cache.put(cacheKey, ctx.getResult());
    }
}

Security Note

These APIs provide low-level access to the request processing pipeline. Use them carefully and ensure proper security measures are in place when modifying request/response handling.

Additional Resources

  • Quarkus Extension Development Guide
  • RESTEasy Reactive SPI Documentation
  • Vert.x Server Handler Documentation

When to Use

Use these advanced integration points when:

  • Building Quarkus extensions
  • Implementing custom observability solutions
  • Creating framework-level integrations
  • Developing custom middleware components
  • Building cross-cutting concerns that need request/response interception

For application-level logic, use standard filters (@ServerRequestFilter, @ServerResponseFilter) instead.