docs
reference
tessl install tessl/maven-io-quarkus--quarkus-rest@3.15.0A Jakarta REST implementation utilizing build time processing and Vert.x for high-performance REST endpoints with reactive programming support, security integration, and cloud-native features.
This guide covers common patterns for building REST APIs with Quarkus REST.
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.*;
import java.util.List;
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class UserResource {
@Inject
UserService userService;
@GET
public List<User> list() {
return userService.listAll();
}
@GET
@Path("/{id}")
public Response get(@PathParam("id") Long id) {
User user = userService.findById(id);
if (user == null) {
return Response.status(404).build();
}
return Response.ok(user).build();
}
@POST
public Response create(User user, @Context UriInfo uriInfo) {
User created = userService.create(user);
URI location = uriInfo.getAbsolutePathBuilder()
.path(created.id.toString())
.build();
return Response.created(location).entity(created).build();
}
@PUT
@Path("/{id}")
public Response update(@PathParam("id") Long id, User user) {
User updated = userService.update(id, user);
if (updated == null) {
return Response.status(404).build();
}
return Response.ok(updated).build();
}
@DELETE
@Path("/{id}")
public Response delete(@PathParam("id") Long id) {
boolean deleted = userService.delete(id);
if (!deleted) {
return Response.status(404).build();
}
return Response.noContent().build();
}
}Type-safe alternative to Response:
import org.jboss.resteasy.reactive.RestResponse;
@Path("/users")
public class UserResource {
@GET
@Path("/{id}")
public RestResponse<User> get(@PathParam("id") Long id) {
User user = userService.findById(id);
if (user == null) {
return RestResponse.notFound();
}
return RestResponse.ok(user);
}
@POST
public RestResponse<User> create(User user) {
User created = userService.create(user);
URI location = URI.create("/users/" + created.id);
return RestResponse.created(location);
}
}Add Bean Validation:
import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
public class User {
@NotBlank
public String name;
@Email
public String email;
@Min(18)
public int age;
}
@Path("/users")
public class UserResource {
@POST
public RestResponse<User> create(@Valid User user) {
// Validation happens automatically
User created = userService.create(user);
return RestResponse.ok(created);
}
}import org.jboss.resteasy.reactive.server.ServerExceptionMapper;
@ApplicationScoped
public class ErrorMappers {
@ServerExceptionMapper
public RestResponse<ErrorResponse> handleValidation(
ValidationException ex) {
return RestResponse.status(422,
new ErrorResponse("Validation failed", ex.getMessage()));
}
@ServerExceptionMapper
public RestResponse<ErrorResponse> handleNotFound(
NotFoundException ex) {
return RestResponse.status(404,
new ErrorResponse("Not found", ex.getMessage()));
}
}@GET
public Response list(
@QueryParam("page") @DefaultValue("0") int page,
@QueryParam("size") @DefaultValue("20") int size) {
List<User> users = userService.list(page, size);
long total = userService.count();
return Response.ok(users)
.header("X-Total-Count", total)
.header("X-Page", page)
.header("X-Page-Size", size)
.build();
}@GET
public List<User> list(
@QueryParam("name") String nameFilter,
@QueryParam("sort") @DefaultValue("name") String sortField,
@QueryParam("order") @DefaultValue("asc") String sortOrder) {
return userService.list(nameFilter, sortField, sortOrder);
}@GET
@Path("/{id}")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public User get(@PathParam("id") Long id) {
return userService.findById(id);
}Client specifies format:
curl -H "Accept: application/json" http://localhost:8080/users/1
curl -H "Accept: application/xml" http://localhost:8080/users/1@Path("/users")
public class UserResource {
@Path("/{userId}/posts")
public PostResource posts(@PathParam("userId") Long userId) {
return new PostResource(userId);
}
}
public class PostResource {
private final Long userId;
public PostResource(Long userId) {
this.userId = userId;
}
@GET
public List<Post> list() {
return postService.findByUser(userId);
}
@POST
public RestResponse<Post> create(Post post) {
post.userId = userId;
return RestResponse.ok(postService.create(post));
}
}@GET
@Path("/{id}")
public Response get(@PathParam("id") Long id) {
User user = userService.findById(id);
return Response.ok(user)
.header("X-Custom-Header", "value")
.header("Cache-Control", "max-age=3600")
.build();
}@GET
@Path("/{id}")
public Response get(
@PathParam("id") Long id,
@HeaderParam("If-None-Match") String ifNoneMatch) {
User user = userService.findById(id);
String etag = computeETag(user);
if (etag.equals(ifNoneMatch)) {
return Response.notModified().tag(etag).build();
}
return Response.ok(user).tag(etag).build();
}See Reactive Programming Guide for async patterns.