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.

response-handling.mddocs/reference/

Response Handling

Quarkus REST provides type-safe response construction through the RestResponse<T> class and declarative annotations for status codes and headers. These features offer a more concise and type-safe alternative to Jakarta REST's Response class.

Import

import org.jboss.resteasy.reactive.RestResponse;
import org.jboss.resteasy.reactive.RestResponse.ResponseBuilder;
import org.jboss.resteasy.reactive.ResponseStatus;
import org.jboss.resteasy.reactive.ResponseHeader;
import jakarta.ws.rs.core.Response.Status;

RestResponse<T>

Type-safe response wrapper that provides compile-time type checking for response entities.

public class RestResponse<T> {
    // Factory methods for common responses
    public static <T> RestResponse<T> ok(T entity);
    public static <T> RestResponse<T> status(Status status);
    public static <T> RestResponse<T> status(Status status, T entity);
    public static <T> RestResponse<T> status(int status);
    public static <T> RestResponse<T> status(int status, T entity);
    public static <T> RestResponse<T> notModified();
    public static <T> RestResponse<T> noContent();
    public static <T> RestResponse<T> accepted();
    public static <T> RestResponse<T> accepted(T entity);
    public static <T> RestResponse<T> notFound();

    // Access response properties
    public int getStatus();
    public T getEntity();
    public <OtherT> OtherT readEntity(Class<OtherT> type);
    public boolean hasEntity();
    public MultivaluedMap<String, Object> getHeaders();
    public String getHeaderString(String name);

    // Convert to Jakarta REST Response
    public Response toResponse();

    // Additional metadata access (inherited from Response)
    public MultivaluedMap<String, Object> getMetadata();
    public MultivaluedMap<String, String> getStringHeaders();
    public MediaType getMediaType();
    public Locale getLanguage();
    public int getLength();
}

Note: RestResponse<T> extends Jakarta REST's Response class and inherits additional methods including getCookies(), getEntityTag(), getDate(), getLastModified(), getLocation(), getLinks(), hasLink(), getLink(), and getLinkBuilder(). Refer to Jakarta REST documentation for complete Response API.

ResponseBuilder<T>

Fluent builder for constructing complex responses.

public static class ResponseBuilder<T> {
    // Start builder chain
    public static <T> ResponseBuilder<T> ok();
    public static <T> ResponseBuilder<T> ok(T entity);
    public static <T> ResponseBuilder<T> status(Status status);
    public static <T> ResponseBuilder<T> status(int status);
    public static <T> ResponseBuilder<T> created(URI location);
    public static <T> ResponseBuilder<T> fromResponse(Response response);

    // Configure response
    public ResponseBuilder<T> status(int status);
    public ResponseBuilder<T> status(Status status);
    public ResponseBuilder<T> entity(T entity);
    public ResponseBuilder<T> header(String name, Object value);
    public ResponseBuilder<T> headers(MultivaluedMap<String, Object> headers);
    public ResponseBuilder<T> type(MediaType type);
    public ResponseBuilder<T> type(String type);
    public ResponseBuilder<T> tag(EntityTag tag);
    public ResponseBuilder<T> tag(String tag);
    public ResponseBuilder<T> lastModified(Date date);
    public ResponseBuilder<T> location(URI location);
    public ResponseBuilder<T> contentLocation(URI location);
    public ResponseBuilder<T> language(String language);
    public ResponseBuilder<T> language(Locale language);
    public ResponseBuilder<T> cookie(NewCookie... cookies);
    public ResponseBuilder<T> expires(Date expires);

    // Build response
    public RestResponse<T> build();
}

Usage Examples

Simple Responses

@GET
@Path("/{id}")
public RestResponse<Item> get(@RestPath String id) {
    Item item = itemService.findById(id);
    if (item == null) {
        return RestResponse.notFound();
    }
    return RestResponse.ok(item);
}

@POST
public RestResponse<Item> create(Item item) {
    Item created = itemService.create(item);
    return RestResponse.status(Status.CREATED, created);
}

@DELETE
@Path("/{id}")
public RestResponse<Void> delete(@RestPath String id) {
    itemService.delete(id);
    return RestResponse.noContent();
}

@PUT
@Path("/{id}")
public RestResponse<Item> update(@RestPath String id, Item item) {
    Item updated = itemService.update(id, item);
    return updated != null
        ? RestResponse.ok(updated)
        : RestResponse.notFound();
}

Builder Pattern

@POST
public RestResponse<Item> create(Item item) {
    Item created = itemService.create(item);
    URI location = URI.create("/items/" + created.getId());

    return RestResponse.ResponseBuilder.created(location)
        .entity(created)
        .header("X-Item-Version", created.getVersion())
        .header("X-Created-By", "system")
        .build();
}

@GET
@Path("/{id}")
public RestResponse<Item> get(@RestPath String id, @RestHeader String ifNoneMatch) {
    Item item = itemService.findById(id);
    if (item == null) {
        return RestResponse.notFound();
    }

    String etag = item.getVersion();
    if (etag.equals(ifNoneMatch)) {
        return RestResponse.notModified();
    }

    return RestResponse.ResponseBuilder.ok(item)
        .tag(etag)
        .lastModified(item.getUpdatedAt())
        .build();
}

@GET
@Path("/download/{id}")
public RestResponse<byte[]> download(@RestPath String id) {
    FileData file = fileService.getFile(id);

    return RestResponse.ResponseBuilder.ok(file.getContent())
        .type("application/octet-stream")
        .header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"")
        .header("Content-Length", file.getSize())
        .build();
}

Accessing Response Properties

@GET
public RestResponse<List<Item>> list() {
    List<Item> items = itemService.findAll();
    RestResponse<List<Item>> response = RestResponse.ok(items);

    // Access response properties
    int status = response.getStatus();
    List<Item> entity = response.getEntity();
    boolean hasEntity = response.hasEntity();

    return response;
}

// Read entity as different type
public void processResponse(RestResponse<?> response) {
    if (response.hasEntity()) {
        String json = response.readEntity(String.class);
        // Process JSON string
    }
}

Declarative Annotations

@ResponseStatus

Sets the HTTP status code declaratively on the resource method.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ResponseStatus {
    int value();  // HTTP status code
}

Usage:

@POST
@ResponseStatus(201)
public Item create(Item item) {
    return itemService.create(item);
}

@DELETE
@Path("/{id}")
@ResponseStatus(204)
public void delete(@RestPath String id) {
    itemService.delete(id);
}

@PUT
@Path("/{id}")
@ResponseStatus(202)
public Item updateAsync(@RestPath String id, Item item) {
    asyncService.scheduleUpdate(id, item);
    return item;
}

@ResponseHeader

Adds response headers declaratively. This annotation is repeatable.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(ResponseHeader.List.class)
public @interface ResponseHeader {
    String name();         // Header name
    String[] value();      // Header value(s)
}

Usage:

@GET
@ResponseHeader(name = "X-Total-Count", value = "100")
public List<Item> list() {
    return itemService.findAll();
}

@GET
@Path("/{id}")
@ResponseHeader(name = "Cache-Control", value = "max-age=3600")
@ResponseHeader(name = "X-Custom", value = "value")
public Item get(@RestPath String id) {
    return itemService.findById(id);
}

@POST
@ResponseStatus(201)
@ResponseHeader(name = "X-Created-By", value = "system")
@ResponseHeader(name = "X-Request-Id", value = "${requestId}")
public Item create(Item item) {
    return itemService.create(item);
}

Type Safety Benefits

RestResponse<T> provides compile-time type safety:

// Type-safe entity access
@GET
@Path("/{id}")
public RestResponse<Item> get(@RestPath String id) {
    Item item = itemService.findById(id);
    RestResponse<Item> response = RestResponse.ok(item);

    // Compile-time checked - entity is Item
    Item entity = response.getEntity();

    return response;
}

// Contrast with Jakarta REST Response
@GET
@Path("/{id}/legacy")
public Response getLegacy(@RestPath String id) {
    Item item = itemService.findById(id);
    Response response = Response.ok(item).build();

    // Runtime cast required - no compile-time safety
    Item entity = (Item) response.getEntity();

    return response;
}

Reactive Responses

RestResponse works seamlessly with reactive types:

@GET
@Path("/{id}")
public Uni<RestResponse<Item>> getAsync(@RestPath String id) {
    return itemService.findByIdAsync(id)
        .map(item -> item != null
            ? RestResponse.ok(item)
            : RestResponse.notFound()
        );
}

@POST
public Uni<RestResponse<Item>> createAsync(Item item) {
    return itemService.createAsync(item)
        .map(created -> RestResponse.status(Status.CREATED, created));
}

Comparison with Jakarta REST Response

FeatureRestResponse<T>Response
Type safety✅ Compile-time❌ Runtime only
Entity accessT getEntity()Object getEntity() (cast required)
Factory methods✅ Type-safe✅ Available
Builder pattern✅ Type-safe✅ Available
JAX-RS compatible✅ Fully compatible✅ Standard

Both RestResponse and Response are fully supported. RestResponse is recommended for new code due to its type safety benefits.