0
# RESTful Web Services
1
2
Quarkus provides RESTEasy Reactive, a high-performance JAX-RS implementation optimized for reactive and imperative programming models with full OpenAPI integration and native compilation support.
3
4
## JAX-RS Core Annotations
5
6
### Resource Path Annotations
7
8
```java { .api }
9
@Target({ElementType.TYPE, ElementType.METHOD})
10
@Retention(RetentionPolicy.RUNTIME)
11
public @interface Path {
12
String value();
13
}
14
```
15
16
Defines the URI path template for a resource class or method.
17
18
**Usage Example:**
19
```java
20
@Path("/users")
21
public class UserResource {
22
23
@GET
24
@Path("/{id}")
25
public User getUser(@PathParam("id") Long id) {
26
return userService.findById(id);
27
}
28
}
29
```
30
31
### HTTP Method Annotations
32
33
```java { .api }
34
@Target(ElementType.METHOD)
35
@Retention(RetentionPolicy.RUNTIME)
36
@HttpMethod("GET")
37
public @interface GET {
38
}
39
40
@Target(ElementType.METHOD)
41
@Retention(RetentionPolicy.RUNTIME)
42
@HttpMethod("POST")
43
public @interface POST {
44
}
45
46
@Target(ElementType.METHOD)
47
@Retention(RetentionPolicy.RUNTIME)
48
@HttpMethod("PUT")
49
public @interface PUT {
50
}
51
52
@Target(ElementType.METHOD)
53
@Retention(RetentionPolicy.RUNTIME)
54
@HttpMethod("DELETE")
55
public @interface DELETE {
56
}
57
58
@Target(ElementType.METHOD)
59
@Retention(RetentionPolicy.RUNTIME)
60
@HttpMethod("HEAD")
61
public @interface HEAD {
62
}
63
64
@Target(ElementType.METHOD)
65
@Retention(RetentionPolicy.RUNTIME)
66
@HttpMethod("OPTIONS")
67
public @interface OPTIONS {
68
}
69
70
@Target(ElementType.METHOD)
71
@Retention(RetentionPolicy.RUNTIME)
72
@HttpMethod("PATCH")
73
public @interface PATCH {
74
}
75
```
76
77
Standard HTTP method annotations for REST endpoints.
78
79
### Content Type Annotations
80
81
```java { .api }
82
@Target({ElementType.TYPE, ElementType.METHOD})
83
@Retention(RetentionPolicy.RUNTIME)
84
public @interface Consumes {
85
String[] value() default {};
86
}
87
88
@Target({ElementType.TYPE, ElementType.METHOD})
89
@Retention(RetentionPolicy.RUNTIME)
90
public @interface Produces {
91
String[] value() default {};
92
}
93
```
94
95
Specify media types for request/response content.
96
97
**Usage Example:**
98
```java
99
@Path("/api/orders")
100
@Produces(MediaType.APPLICATION_JSON)
101
@Consumes(MediaType.APPLICATION_JSON)
102
public class OrderResource {
103
104
@POST
105
public Response createOrder(Order order) {
106
Order created = orderService.create(order);
107
return Response.status(Response.Status.CREATED).entity(created).build();
108
}
109
}
110
```
111
112
## Parameter Injection Annotations
113
114
### Path and Query Parameters
115
116
```java { .api }
117
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
118
@Retention(RetentionPolicy.RUNTIME)
119
public @interface PathParam {
120
String value();
121
}
122
123
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
124
@Retention(RetentionPolicy.RUNTIME)
125
public @interface QueryParam {
126
String value();
127
}
128
129
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
130
@Retention(RetentionPolicy.RUNTIME)
131
public @interface MatrixParam {
132
String value();
133
}
134
135
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
136
@Retention(RetentionPolicy.RUNTIME)
137
public @interface FormParam {
138
String value();
139
}
140
```
141
142
Parameter extraction annotations for different HTTP parameter types.
143
144
**Usage Example:**
145
```java
146
@Path("/search")
147
public class SearchResource {
148
149
@GET
150
public List<Product> search(@QueryParam("q") String query,
151
@QueryParam("limit") @DefaultValue("10") int limit,
152
@QueryParam("offset") @DefaultValue("0") int offset) {
153
return searchService.search(query, limit, offset);
154
}
155
}
156
```
157
158
### Header and Cookie Parameters
159
160
```java { .api }
161
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
162
@Retention(RetentionPolicy.RUNTIME)
163
public @interface HeaderParam {
164
String value();
165
}
166
167
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
168
@Retention(RetentionPolicy.RUNTIME)
169
public @interface CookieParam {
170
String value();
171
}
172
```
173
174
Extract values from HTTP headers and cookies.
175
176
### Context Injection
177
178
```java { .api }
179
@Target({ElementType.PARAMETER, ElementType.FIELD})
180
@Retention(RetentionPolicy.RUNTIME)
181
public @interface Context {
182
}
183
```
184
185
Inject JAX-RS context objects like `UriInfo`, `HttpHeaders`, `SecurityContext`, etc.
186
187
**Usage Example:**
188
```java
189
@GET
190
@Path("/info")
191
public Response getRequestInfo(@Context UriInfo uriInfo,
192
@Context HttpHeaders headers,
193
@Context SecurityContext securityContext) {
194
Map<String, Object> info = Map.of(
195
"uri", uriInfo.getRequestUri().toString(),
196
"userAgent", headers.getHeaderString("User-Agent"),
197
"authenticated", securityContext.getUserPrincipal() != null
198
);
199
return Response.ok(info).build();
200
}
201
```
202
203
## Response Building
204
205
### Response Class
206
207
```java { .api }
208
public abstract class Response {
209
public static ResponseBuilder status(Status status);
210
public static ResponseBuilder status(int status);
211
public static ResponseBuilder ok();
212
public static ResponseBuilder ok(Object entity);
213
public static ResponseBuilder created(URI location);
214
public static ResponseBuilder noContent();
215
public static ResponseBuilder notModified();
216
217
public abstract int getStatus();
218
public abstract Object getEntity();
219
public abstract MultivaluedMap<String, Object> getMetadata();
220
}
221
```
222
223
Core response building functionality.
224
225
```java { .api }
226
public abstract static class ResponseBuilder {
227
public abstract Response build();
228
public abstract ResponseBuilder entity(Object entity);
229
public abstract ResponseBuilder type(MediaType type);
230
public abstract ResponseBuilder type(String type);
231
public abstract ResponseBuilder header(String name, Object value);
232
public abstract ResponseBuilder cookie(NewCookie... cookies);
233
public abstract ResponseBuilder status(Status status);
234
public abstract ResponseBuilder status(int status);
235
}
236
```
237
238
Builder for constructing HTTP responses.
239
240
**Usage Example:**
241
```java
242
@POST
243
@Path("/users")
244
public Response createUser(User user) {
245
try {
246
User created = userService.create(user);
247
return Response.created(
248
URI.create("/users/" + created.getId())
249
).entity(created).build();
250
} catch (ValidationException e) {
251
return Response.status(Response.Status.BAD_REQUEST)
252
.entity(Map.of("error", e.getMessage()))
253
.build();
254
}
255
}
256
```
257
258
### Status Enum
259
260
```java { .api }
261
public enum Status {
262
OK(200, "OK"),
263
CREATED(201, "Created"),
264
ACCEPTED(202, "Accepted"),
265
NO_CONTENT(204, "No Content"),
266
MOVED_PERMANENTLY(301, "Moved Permanently"),
267
FOUND(302, "Found"),
268
NOT_MODIFIED(304, "Not Modified"),
269
BAD_REQUEST(400, "Bad Request"),
270
UNAUTHORIZED(401, "Unauthorized"),
271
FORBIDDEN(403, "Forbidden"),
272
NOT_FOUND(404, "Not Found"),
273
METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
274
CONFLICT(409, "Conflict"),
275
INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
276
SERVICE_UNAVAILABLE(503, "Service Unavailable");
277
278
public int getStatusCode();
279
public String getReasonPhrase();
280
}
281
```
282
283
Standard HTTP status codes.
284
285
## Exception Handling
286
287
### Exception Mappers
288
289
```java { .api }
290
public interface ExceptionMapper<T extends Throwable> {
291
Response toResponse(T exception);
292
}
293
```
294
295
Interface for mapping exceptions to HTTP responses.
296
297
**Usage Example:**
298
```java
299
@Provider
300
public class ValidationExceptionMapper implements ExceptionMapper<ValidationException> {
301
302
@Override
303
public Response toResponse(ValidationException exception) {
304
return Response.status(Response.Status.BAD_REQUEST)
305
.entity(Map.of("error", exception.getMessage()))
306
.build();
307
}
308
}
309
```
310
311
### WebApplicationException
312
313
```java { .api }
314
public class WebApplicationException extends RuntimeException {
315
public WebApplicationException();
316
public WebApplicationException(String message);
317
public WebApplicationException(Response response);
318
public WebApplicationException(int status);
319
public WebApplicationException(Status status);
320
321
public Response getResponse();
322
}
323
```
324
325
Runtime exception that automatically maps to HTTP responses.
326
327
## Filters and Interceptors
328
329
### Request and Response Filters
330
331
```java { .api }
332
public interface ContainerRequestFilter {
333
void filter(ContainerRequestContext requestContext) throws IOException;
334
}
335
336
public interface ContainerResponseFilter {
337
void filter(ContainerRequestContext requestContext,
338
ContainerResponseContext responseContext) throws IOException;
339
}
340
```
341
342
Interfaces for filtering HTTP requests and responses.
343
344
**Usage Example:**
345
```java
346
@Provider
347
@PreMatching
348
public class LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter {
349
350
@Override
351
public void filter(ContainerRequestContext requestContext) {
352
System.out.println("Request: " + requestContext.getMethod() + " " +
353
requestContext.getUriInfo().getPath());
354
}
355
356
@Override
357
public void filter(ContainerRequestContext requestContext,
358
ContainerResponseContext responseContext) {
359
System.out.println("Response: " + responseContext.getStatus());
360
}
361
}
362
```
363
364
### Filter Annotations
365
366
```java { .api }
367
@Target(ElementType.TYPE)
368
@Retention(RetentionPolicy.RUNTIME)
369
public @interface PreMatching {
370
}
371
372
@Target({ElementType.TYPE, ElementType.METHOD})
373
@Retention(RetentionPolicy.RUNTIME)
374
public @interface Provider {
375
}
376
```
377
378
Annotations for configuring filters and providers.
379
380
## Reactive Support
381
382
### Reactive Return Types
383
384
```java { .api }
385
// Mutiny Uni for single async values
386
@GET
387
@Path("/async-user/{id}")
388
public Uni<User> getUserAsync(@PathParam("id") Long id) {
389
return userService.findByIdAsync(id);
390
}
391
392
// Mutiny Multi for streaming responses
393
@GET
394
@Path("/stream/users")
395
@Produces(MediaType.SERVER_SENT_EVENTS)
396
public Multi<User> streamUsers() {
397
return userService.streamAll();
398
}
399
400
// CompletionStage for async responses
401
@GET
402
@Path("/future-user/{id}")
403
public CompletionStage<User> getUserFuture(@PathParam("id") Long id) {
404
return userService.findByIdFuture(id);
405
}
406
```
407
408
RESTEasy Reactive supports reactive return types for non-blocking operations.
409
410
## OpenAPI Integration
411
412
### OpenAPI Annotations
413
414
```java { .api }
415
@Target({ElementType.TYPE, ElementType.METHOD})
416
@Retention(RetentionPolicy.RUNTIME)
417
public @interface Operation {
418
String summary() default "";
419
String description() default "";
420
String operationId() default "";
421
String[] tags() default {};
422
}
423
424
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
425
@Retention(RetentionPolicy.RUNTIME)
426
public @interface Parameter {
427
String name() default "";
428
String description() default "";
429
boolean required() default false;
430
ParameterIn in() default ParameterIn.DEFAULT;
431
}
432
433
@Target({ElementType.METHOD, ElementType.TYPE})
434
@Retention(RetentionPolicy.RUNTIME)
435
public @interface APIResponse {
436
String responseCode() default "default";
437
String description() default "";
438
Class<?> content() default Void.class;
439
}
440
```
441
442
OpenAPI documentation annotations for API specification generation.
443
444
**Usage Example:**
445
```java
446
@Path("/users")
447
@Tag(name = "Users", description = "User management operations")
448
public class UserResource {
449
450
@GET
451
@Path("/{id}")
452
@Operation(summary = "Get user by ID", description = "Retrieves a user by their unique identifier")
453
@APIResponse(responseCode = "200", description = "User found", content = User.class)
454
@APIResponse(responseCode = "404", description = "User not found")
455
public Response getUser(@Parameter(description = "User ID") @PathParam("id") Long id) {
456
User user = userService.findById(id);
457
if (user != null) {
458
return Response.ok(user).build();
459
} else {
460
return Response.status(Response.Status.NOT_FOUND).build();
461
}
462
}
463
}
464
```
465
466
## WebSocket Support
467
468
### WebSocket Annotations
469
470
```java { .api }
471
@Target(ElementType.TYPE)
472
@Retention(RetentionPolicy.RUNTIME)
473
public @interface WebSocket {
474
String path() default "";
475
}
476
477
@Target(ElementType.TYPE)
478
@Retention(RetentionPolicy.RUNTIME)
479
public @interface WebSocketClient {
480
String path() default "";
481
}
482
```
483
484
Annotations for defining WebSocket endpoints and clients.
485
486
### WebSocket Message Handling
487
488
```java { .api }
489
@Target(ElementType.METHOD)
490
@Retention(RetentionPolicy.RUNTIME)
491
public @interface OnTextMessage {
492
}
493
494
@Target(ElementType.METHOD)
495
@Retention(RetentionPolicy.RUNTIME)
496
public @interface OnBinaryMessage {
497
}
498
499
@Target(ElementType.METHOD)
500
@Retention(RetentionPolicy.RUNTIME)
501
public @interface OnOpen {
502
}
503
504
@Target(ElementType.METHOD)
505
@Retention(RetentionPolicy.RUNTIME)
506
public @interface OnClose {
507
}
508
509
@Target(ElementType.METHOD)
510
@Retention(RetentionPolicy.RUNTIME)
511
public @interface OnError {
512
}
513
```
514
515
Annotations for WebSocket lifecycle and message handling methods.
516
517
**Usage Example:**
518
```java
519
@WebSocket(path = "/chat")
520
public class ChatSocket {
521
522
@OnOpen
523
public void onOpen(WebSocketConnection connection) {
524
System.out.println("Client connected: " + connection.id());
525
}
526
527
@OnTextMessage
528
public void onMessage(String message, WebSocketConnection connection) {
529
// Broadcast message to all connections
530
connection.broadcast().sendTextAndAwait(message);
531
}
532
533
@OnClose
534
public void onClose(WebSocketConnection connection) {
535
System.out.println("Client disconnected: " + connection.id());
536
}
537
}
538
```
539
540
## Client Support
541
542
### REST Client Interface
543
544
```java { .api }
545
@Target(ElementType.TYPE)
546
@Retention(RetentionPolicy.RUNTIME)
547
public @interface RegisterRestClient {
548
String configKey() default "";
549
String baseUri() default "";
550
}
551
```
552
553
Annotation for registering REST client interfaces.
554
555
**Usage Example:**
556
```java
557
@RegisterRestClient(configKey = "user-service")
558
@Path("/users")
559
public interface UserServiceClient {
560
561
@GET
562
@Path("/{id}")
563
User getUser(@PathParam("id") Long id);
564
565
@POST
566
User createUser(User user);
567
}
568
569
// Usage in a service
570
@ApplicationScoped
571
public class ExternalUserService {
572
573
@RestClient
574
UserServiceClient userClient;
575
576
public User getExternalUser(Long id) {
577
return userClient.getUser(id);
578
}
579
}
580
```