Quarkus REST (RESTEasy Reactive)
JAX-RS endpoints with RESTEasy Reactive — request validation and response models.
# CLAUDE.md — Quarkus REST (RESTEasy Reactive)
## Extension choice
- Use **`quarkus-rest`** (RESTEasy Reactive). It's the modern default — built-in reactive, faster, smaller native image.
- The classic `quarkus-resteasy` (non-reactive) is legacy. Don't start new projects with it.
- For a fully reactive stack, pair with `quarkus-rest-jackson` (or `quarkus-rest-jsonb`) for JSON.
## Resource classes
- `@Path("/users")` on a class. Methods use JAX-RS annotations: `@GET`, `@POST`, `@Path("/{id}")`.
- Don't use `@ApplicationScoped` on resources unless you understand the lifecycle. RESTEasy Reactive handles this for you.
- Inject services via constructor (`@Inject` on the constructor params is implicit in Quarkus).
## Reactive vs imperative
- Methods can return `T` (blocking, runs on the worker thread) or `Uni<T>` / `Multi<T>` (reactive, runs on the event loop).
- For purely reactive workloads, return `Uni<T>`. For mixed code, blocking is fine — Quarkus dispatches automatically.
- Annotate with `@RunOnVirtualThread` (Quarkus 3.10+) to opt in to virtual-thread dispatch — best of both worlds.
## Request/response shaping
- Records as DTOs. Use `@JsonbProperty` or Jackson's `@JsonProperty` to rename fields when client contracts diverge.
- Validate with Bean Validation: `@Valid` on the body parameter, `@NotNull` / `@Email` / `@Size` on fields.
- For errors, throw `WebApplicationException` with a status — or define an `ExceptionMapper`.
## Exception mapping
- One `ExceptionMapper<X>` per error type. Quarkus auto-discovers them.
- Use `RestResponse<T>` to return typed responses with status:
```java
RestResponse<UserDto> get(@PathParam("id") String id) {
var user = service.find(id);
return user.map(RestResponse::ok)
.orElseGet(() -> RestResponse.status(404));
}
```
## Validation errors
- `ConstraintViolationException` is auto-mapped to a 400 with field-level errors. Customize via a custom mapper.
- For consistent error envelopes, define a `ProblemDetail`-like DTO and use it everywhere.
## OpenAPI
- Add `quarkus-smallrye-openapi`. The spec is exposed at `/q/openapi`, Swagger UI at `/q/swagger-ui`.
- Annotate with `@Operation`, `@APIResponse` for richer docs. Most generation is automatic from JAX-RS + Bean Validation.
## CORS
- Enable globally: `quarkus.http.cors=true`, `quarkus.http.cors.origins=https://app.example.com`.
- Don't set `*` with credentials. The browser will refuse.
## Don't
- Don't mix RESTEasy Reactive and non-reactive in the same project.
- Don't return `Response.ok().entity(x).build()` when `RestResponse.ok(x)` does the same with type safety.
- Don't put logic in `ExceptionMapper`. They translate; logic belongs in services.
- Don't disable native compilation tests for new endpoints. RESTEasy works in native, but reflection-heavy custom code might not.
Other Java templates
Modern Java Rules
Java 21+ defaults: records, sealed types, pattern matching, virtual threads, var.
Java Testing with JUnit 5
JUnit 5 + AssertJ + Mockito + Testcontainers — opinionated test conventions.
Java Virtual Threads & Concurrency
Project Loom virtual threads, structured concurrency, and modern concurrent patterns.
Java Build (Maven & Gradle)
Build conventions, dependency management, multi-module projects, and CI patterns.
Java Streams & Collections
Streams API, immutable collections, Collectors, and idiomatic data manipulation.