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.

resource-utilities.mddocs/reference/

Resource Utilities

Quarkus REST provides utility interfaces for resource metadata access and resource cleanup.

Import

import org.jboss.resteasy.reactive.server.SimpleResourceInfo;
import io.quarkus.resteasy.reactive.server.Closer;
import jakarta.ws.rs.core.Context;

SimpleResourceInfo

Lightweight interface providing resource method metadata.

public interface SimpleResourceInfo {
    Class<?> getResourceClass();  // Resource class containing the method
    String getMethodName();        // Method name
    Class<?>[] parameterTypes();   // Parameter types array
}

Usage in Filters

@ServerRequestFilter
public Optional<Response> filter(SimpleResourceInfo resourceInfo) {
    Class<?> resourceClass = resourceInfo.getResourceClass();
    String methodName = resourceInfo.getMethodName();
    Class<?>[] paramTypes = resourceInfo.parameterTypes();

    logger.info("Executing {}.{}({})",
        resourceClass.getSimpleName(),
        methodName,
        Arrays.toString(paramTypes)
    );

    return Optional.empty();
}

Usage in Exception Mappers

@ServerExceptionMapper
public Response mapException(
    BusinessException ex,
    SimpleResourceInfo resourceInfo
) {
    ErrorResponse error = new ErrorResponse();
    error.setMessage(ex.getMessage());
    error.setResource(resourceInfo.getResourceClass().getSimpleName());
    error.setMethod(resourceInfo.getMethodName());

    return Response.status(400).entity(error).build();
}

Conditional Logic Based on Resource

@ServerRequestFilter
public Optional<Response> filter(SimpleResourceInfo resourceInfo) {
    // Apply logic only to specific resources
    if (resourceInfo.getResourceClass().equals(AdminResource.class)) {
        if (!securityService.isAdmin()) {
            return Optional.of(Response.status(403).build());
        }
    }

    return Optional.empty();
}

Closer

Interface for registering resources to be closed after request completion.

public interface Closer {
    /**
     * Register a new Closeable that is to be closed when the request completes.
     */
    void add(Closeable closeable);
}

Usage in Resource Methods

@GET
@Path("/{id}/download")
public Response download(@RestPath String id, @Context Closer closer) throws IOException {
    InputStream stream = fileService.openStream(id);

    // Register for automatic cleanup
    closer.add(stream);

    return Response.ok(stream)
        .type("application/octet-stream")
        .build();
}

Multiple Resources

@GET
@Path("/combined")
public Response getCombined(@Context Closer closer) throws IOException {
    InputStream stream1 = service1.openStream();
    InputStream stream2 = service2.openStream();
    Connection conn = database.getConnection();

    // Register all for cleanup
    closer.add(stream1);
    closer.add(stream2);
    closer.add(conn);

    CombinedData data = processStreams(stream1, stream2, conn);

    return Response.ok(data).build();
}

With Database Resources

@GET
@Path("/query")
public Response query(@RestQuery String sql, @Context Closer closer) throws SQLException {
    Connection conn = dataSource.getConnection();
    closer.add(conn);

    Statement stmt = conn.createStatement();
    closer.add(stmt);

    ResultSet rs = stmt.executeQuery(sql);
    closer.add(rs);

    List<Map<String, Object>> results = processResultSet(rs);

    return Response.ok(results).build();
}

With Custom Resources

public class CustomResource implements Closeable {
    @Override
    public void close() throws IOException {
        // Cleanup logic
    }
}

@GET
@Path("/custom")
public Response getCustom(@Context Closer closer) {
    CustomResource resource = new CustomResource();
    closer.add(resource);

    Data data = resource.getData();

    return Response.ok(data).build();
}

Comparison with ResourceInfo

SimpleResourceInfo is a lightweight alternative to JAX-RS's ResourceInfo:

FeatureSimpleResourceInfoResourceInfo
Resource classgetResourceClass()getResourceClass()
Method infogetMethodName(), parameterTypes()getResourceMethod() (full Method object)
Performance✅ Lightweight❌ Heavier (full reflection)
Use caseFilters, mappersComplex reflection needs

Use SimpleResourceInfo unless you need full Method reflection:

// SimpleResourceInfo (preferred for filters)
@ServerRequestFilter
public void filter(SimpleResourceInfo info) {
    String methodName = info.getMethodName();
}

// ResourceInfo (for complex reflection)
@ServerRequestFilter
public void filter(ResourceInfo info) {
    Method method = info.getResourceMethod();
    Annotation[] annotations = method.getAnnotations();
}

Closer Guarantees

Resources registered with Closer are guaranteed to be closed:

  • On success: After response is sent
  • On error: After exception mapper runs
  • On abort: Even if request is aborted
  • Order: Resources closed in reverse registration order (LIFO)
@GET
public Response get(@Context Closer closer) {
    Closeable first = openFirst();
    closer.add(first);

    Closeable second = openSecond();
    closer.add(second);

    // Closed in order: second, then first
    return Response.ok().build();
}

Integration with Try-With-Resources

Closer complements try-with-resources for response streaming:

// Don't use try-with-resources for response streaming
@GET
public Response streamBad(@Context Closer closer) {
    try (InputStream stream = openStream()) {
        // BAD: Stream closed before response sent
        return Response.ok(stream).build();
    }
}

// Use Closer instead
@GET
public Response streamGood(@Context Closer closer) {
    InputStream stream = openStream();
    closer.add(stream);  // Closed after response sent
    return Response.ok(stream).build();
}

Error Handling

Closer logs but doesn't throw exceptions during cleanup:

@GET
public Response get(@Context Closer closer) {
    Closeable resource = new Closeable() {
        @Override
        public void close() throws IOException {
            throw new IOException("Close failed");
        }
    };

    closer.add(resource);

    // Close exception is logged, not thrown
    return Response.ok().build();
}