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 Jakarta EE templates
Modern Quarkus Rules
Quarkus 3+ defaults: dev mode, build-time optimization, configuration, and CDI.
Quarkus + Hibernate ORM with Panache
Active-record and repository styles with Panache, Flyway migrations, transactions.
Modern Jakarta EE Rules
Jakarta EE 10+ namespace migration, modular architecture, and platform conventions.
Jakarta CDI
CDI scopes, qualifiers, producers, events, and the lifecycle to actually understand.
Jakarta Persistence (JPA)
Entities, fetch strategies, JPQL, transactions, and L2 cache discipline.