REST framework offering the route model to define non blocking endpoints
—
Core functionality for defining HTTP endpoints using declarative annotations. Supports path-based and regex-based routing with comprehensive HTTP method and content-type configuration.
Primary annotation for defining reactive routes on methods. Provides comprehensive configuration options for HTTP routing, content types, and handler behavior.
/**
* Defines a reactive route on a method
* Can be repeated using @Routes container annotation
*/
@Route(
path = "/api/users/:id", // Path-based routing with parameters
regex = ".*\\.json$", // Alternative regex-based routing
methods = HttpMethod.GET, // HTTP methods (single or array)
produces = {"application/json"}, // Response content types
consumes = {"application/json"}, // Request content types
type = Route.HandlerType.NORMAL, // Handler execution type
order = 100 // Route ordering priority
)
public String handleRequest() {
return "response";
}Usage Examples:
import io.quarkus.vertx.web.Route;
import io.quarkus.vertx.web.Route.HttpMethod;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class ProductRoutes {
// Simple GET route
@Route(path = "/products", methods = HttpMethod.GET)
public String listProducts() {
return "Product list";
}
// Route with path parameters
@Route(path = "/products/:id", methods = HttpMethod.GET)
public String getProduct(@Param("id") String productId) {
return "Product: " + productId;
}
// Route with multiple HTTP methods
@Route(path = "/products/:id", methods = {HttpMethod.PUT, HttpMethod.PATCH})
public String updateProduct(@Param("id") String id, @Body Product product) {
return "Updated product: " + id;
}
// Route with content type restrictions
@Route(
path = "/products",
methods = HttpMethod.POST,
consumes = "application/json",
produces = "application/json"
)
public String createProduct(@Body Product product) {
return "Created: " + product.getName();
}
// Regex-based routing
@Route(regex = "/files/.*\\.pdf$", methods = HttpMethod.GET)
public String servePdf(RoutingExchange exchange) {
String path = exchange.request().path();
return "Serving PDF: " + path;
}
}Container annotation that allows multiple @Route annotations on a single method.
/**
* Container annotation for multiple @Route declarations on a single method
* Automatically applied when using multiple @Route annotations
*/
@interface Routes {
Route[] value();
}
// Usage - multiple @Route annotations are automatically wrapped in @Routes
@Route(path = "/api/v1/users", methods = HttpMethod.GET)
@Route(path = "/api/v2/users", methods = HttpMethod.GET)
public String getUsers() {
return "Users";
}
// Explicit usage (equivalent to above)
@Routes({
@Route(path = "/api/v1/users", methods = HttpMethod.GET),
@Route(path = "/api/v2/users", methods = HttpMethod.GET)
})
public String getUsersExplicit() {
return "Users";
}Provides default configuration for all routes declared within a class, reducing repetitive annotation parameters.
/**
* Configures default route settings for all routes in a class
* Individual @Route annotations can override these defaults
*/
@RouteBase(
path = "/api/v1", // Path prefix for all routes
produces = {"application/json"}, // Default response content type
consumes = {"application/json"} // Default request content type
)
public class ApiController {
@Route(path = "/users", methods = HttpMethod.GET) // Becomes /api/v1/users
public String getUsers() {
return "Users";
}
@Route(path = "/products", methods = HttpMethod.GET, produces = "text/plain")
// Becomes /api/v1/products with overridden content type
public String getProducts() {
return "Products";
}
}Defines supported HTTP methods for route configuration.
public enum Route.HttpMethod {
GET, // HTTP GET requests
HEAD, // HTTP HEAD requests
POST, // HTTP POST requests
PUT, // HTTP PUT requests
DELETE, // HTTP DELETE requests
OPTIONS // HTTP OPTIONS requests
}Specifies the execution model for route handlers.
public enum Route.HandlerType {
NORMAL, // Non-blocking execution (default)
BLOCKING, // Blocking execution on worker thread
FAILURE; // Failure handler for error processing
/**
* Convert string value to HandlerType
* @param value String representation
* @return Corresponding HandlerType
*/
public static HandlerType from(String value);
}Handler Type Usage:
// Non-blocking handler (default)
@Route(path = "/async", methods = HttpMethod.GET, type = Route.HandlerType.NORMAL)
public Uni<String> asyncOperation() {
return Uni.createFrom().item("Async result");
}
// Blocking handler for I/O operations
@Route(path = "/blocking", methods = HttpMethod.GET, type = Route.HandlerType.BLOCKING)
public String blockingOperation() {
// Blocking I/O operation
return "Blocking result";
}
// Failure handler
@Route(path = "/error-handler", type = Route.HandlerType.FAILURE)
public String handleError(RoutingExchange exchange) {
Throwable failure = exchange.context().failure();
return "Error: " + failure.getMessage();
}Standard path-based routing with support for path parameters and wildcards.
// Static path
@Route(path = "/users", methods = HttpMethod.GET)
// Path with single parameter
@Route(path = "/users/:id", methods = HttpMethod.GET)
// Path with multiple parameters
@Route(path = "/users/:userId/posts/:postId", methods = HttpMethod.GET)
// Wildcard matching
@Route(path = "/files/*", methods = HttpMethod.GET)Advanced routing using regular expressions for complex path matching.
// File extension matching
@Route(regex = ".*\\.json$", methods = HttpMethod.GET)
// Version-specific API matching
@Route(regex = "/api/v[0-9]+/users", methods = HttpMethod.GET)
// Complex pattern matching
@Route(regex = "/products/[a-zA-Z0-9]{8,12}", methods = HttpMethod.GET)Control route evaluation order using the order attribute. Lower values are evaluated first.
@Route(path = "/special/*", methods = HttpMethod.GET, order = 1)
public String specialHandler() { return "Special"; }
@Route(path = "/*", methods = HttpMethod.GET, order = 1000)
public String fallbackHandler() { return "Fallback"; }Class-level annotation that provides defaults for all route methods within a class, reducing repetition and providing consistent configuration.
/**
* Annotation for configuring class-level defaults for reactive routes
*/
@RouteBase(
path = "/api/v1", // Path prefix for all routes in class
produces = {"application/json"}, // Default response content type
consumes = {"application/json"} // Default request content type
)
public @interface RouteBase {
String path() default "";
String[] produces() default {};
String[] consumes() default {};
}Usage Examples:
import io.quarkus.vertx.web.Route;
import io.quarkus.vertx.web.RouteBase;
import io.quarkus.vertx.web.Route.HttpMethod;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
@RouteBase(path = "/api/users", produces = "application/json")
public class UserRoutes {
// Effective path: /api/users (base + empty path)
@Route(methods = HttpMethod.GET)
public String listUsers() {
return "{\"users\": []}";
}
// Effective path: /api/users/:id (base + relative path)
@Route(path = "/:id", methods = HttpMethod.GET)
public String getUser(@Param("id") String id) {
return "{\"user\": {\"id\": \"" + id + "\"}}";
}
// Override base produces setting
@Route(path = "/:id/avatar", methods = HttpMethod.GET, produces = "image/png")
public byte[] getUserAvatar(@Param("id") String id) {
return loadAvatarBytes(id);
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-quarkus--quarkus-reactive-routes