or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdconfiguration.mdcore-application.mddatabase.mdindex.mdmetrics.mdrest-api.mdtesting.mdvalidation.md

rest-api.mddocs/

0

# REST API Development

1

2

Jersey (JAX-RS) integration for building RESTful web services with automatic JSON serialization, validation, and metrics collection.

3

4

## Capabilities

5

6

### Jersey Environment

7

8

The Jersey environment provides methods for registering JAX-RS resources, providers, filters, and other components.

9

10

```java { .api }

11

package io.dropwizard.jersey.setup;

12

13

public class JerseyEnvironment {

14

/**

15

* Registers a JAX-RS component (resource, provider, filter, etc.).

16

*/

17

public void register(Object component);

18

19

/**

20

* Registers a JAX-RS component class.

21

*/

22

public void register(Class<?> componentClass);

23

24

/**

25

* Registers all JAX-RS components in the given packages.

26

*/

27

public void packages(String... packages);

28

29

/**

30

* Registers all JAX-RS components in the given packages recursively.

31

*/

32

public void packages(boolean recursive, String... packages);

33

34

/**

35

* Returns the Jersey resource configuration.

36

*/

37

public DropwizardResourceConfig getResourceConfig();

38

39

/**

40

* Sets the URL pattern for Jersey servlet.

41

*/

42

public void setUrlPattern(String urlPattern);

43

}

44

```

45

46

**Usage Example:**

47

48

```java

49

@Override

50

public void run(MyConfiguration configuration, Environment environment) {

51

// Register individual resources

52

environment.jersey().register(new HelloWorldResource());

53

environment.jersey().register(new UserResource());

54

55

// Register all resources in a package

56

environment.jersey().packages("com.example.resources");

57

58

// Register providers and filters

59

environment.jersey().register(new CORSFilter());

60

environment.jersey().register(new LoggingFilter());

61

}

62

```

63

64

### JAX-RS Resource Development

65

66

Standard JAX-RS annotations and patterns for building REST endpoints with Dropwizard enhancements.

67

68

```java { .api }

69

// Path and HTTP method annotations

70

@Path("/users")

71

@GET @POST @PUT @DELETE @HEAD @OPTIONS

72

73

// Content type annotations

74

@Produces(MediaType.APPLICATION_JSON)

75

@Consumes(MediaType.APPLICATION_JSON)

76

77

// Parameter annotations

78

@PathParam("id") @QueryParam("name") @FormParam("value")

79

@HeaderParam("X-Custom") @CookieParam("session")

80

81

// Validation annotations

82

@Valid @NotNull @NotEmpty

83

84

// Dropwizard metric annotations

85

@Timed @Metered @Counted @ExceptionMetered

86

87

// Caching annotations

88

@CacheControl(maxAge = 300, maxAgeUnit = TimeUnit.SECONDS)

89

```

90

91

**Usage Example:**

92

93

```java

94

@Path("/users")

95

@Produces(MediaType.APPLICATION_JSON)

96

@Consumes(MediaType.APPLICATION_JSON)

97

public class UserResource {

98

private final UserService userService;

99

100

public UserResource(UserService userService) {

101

this.userService = userService;

102

}

103

104

@GET

105

@Timed(name = "get-users")

106

@CacheControl(maxAge = 5, maxAgeUnit = TimeUnit.MINUTES)

107

public List<User> getUsers(@QueryParam("active") @DefaultValue("true") boolean active,

108

@QueryParam("limit") @DefaultValue("100") @Range(min = 1, max = 1000) int limit) {

109

return userService.findUsers(active, limit);

110

}

111

112

@GET

113

@Path("/{id}")

114

@Timed(name = "get-user-by-id")

115

public Optional<User> getUser(@PathParam("id") @NotNull Long id) {

116

return userService.findById(id);

117

}

118

119

@POST

120

@Timed(name = "create-user")

121

public Response createUser(@Valid @NotNull User user, @Context UriInfo uriInfo) {

122

User created = userService.create(user);

123

URI location = uriInfo.getAbsolutePathBuilder()

124

.path(created.getId().toString())

125

.build();

126

return Response.created(location).entity(created).build();

127

}

128

129

@PUT

130

@Path("/{id}")

131

@Timed(name = "update-user")

132

public User updateUser(@PathParam("id") @NotNull Long id,

133

@Valid @NotNull User user) {

134

return userService.update(id, user);

135

}

136

137

@DELETE

138

@Path("/{id}")

139

@Timed(name = "delete-user")

140

public Response deleteUser(@PathParam("id") @NotNull Long id) {

141

userService.delete(id);

142

return Response.noContent().build();

143

}

144

}

145

```

146

147

### Exception Handling

148

149

Custom exception mappers for converting exceptions to HTTP responses with proper status codes and error messages.

150

151

```java { .api }

152

package javax.ws.rs.ext;

153

154

@Provider

155

public interface ExceptionMapper<T extends Throwable> {

156

/**

157

* Maps an exception to a Response.

158

*/

159

Response toResponse(T exception);

160

}

161

```

162

163

**Usage Example:**

164

165

```java

166

@Provider

167

public class ValidationExceptionMapper implements ExceptionMapper<ConstraintViolationException> {

168

@Override

169

public Response toResponse(ConstraintViolationException exception) {

170

List<String> errors = exception.getConstraintViolations()

171

.stream()

172

.map(ConstraintViolation::getMessage)

173

.collect(Collectors.toList());

174

175

return Response.status(Response.Status.BAD_REQUEST)

176

.entity(new ErrorResponse("Validation failed", errors))

177

.build();

178

}

179

}

180

181

// Register the exception mapper

182

environment.jersey().register(new ValidationExceptionMapper());

183

```

184

185

### Response Filters and Providers

186

187

JAX-RS providers for custom request/response processing including filters, interceptors, and message body readers/writers.

188

189

```java { .api }

190

package javax.ws.rs.container;

191

192

@Provider

193

public interface ContainerRequestFilter {

194

void filter(ContainerRequestContext requestContext) throws IOException;

195

}

196

197

@Provider

198

public interface ContainerResponseFilter {

199

void filter(ContainerRequestContext requestContext,

200

ContainerResponseContext responseContext) throws IOException;

201

}

202

```

203

204

**Usage Example:**

205

206

```java

207

@Provider

208

public class CORSFilter implements ContainerResponseFilter {

209

@Override

210

public void filter(ContainerRequestContext requestContext,

211

ContainerResponseContext responseContext) throws IOException {

212

responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");

213

responseContext.getHeaders().add("Access-Control-Allow-Methods",

214

"GET, POST, PUT, DELETE, OPTIONS");

215

responseContext.getHeaders().add("Access-Control-Allow-Headers",

216

"Content-Type, Authorization");

217

}

218

}

219

220

@Provider

221

@PreMatching

222

public class LoggingFilter implements ContainerRequestFilter {

223

private static final Logger LOGGER = LoggerFactory.getLogger(LoggingFilter.class);

224

225

@Override

226

public void filter(ContainerRequestContext requestContext) throws IOException {

227

LOGGER.info("Processing {} request to {}",

228

requestContext.getMethod(),

229

requestContext.getUriInfo().getPath());

230

}

231

}

232

```

233

234

### JSON Configuration

235

236

Customize Jackson ObjectMapper configuration for JSON serialization and deserialization.

237

238

```java { .api }

239

package io.dropwizard.jackson;

240

241

public class ObjectMapperFactory {

242

/**

243

* Builds a new ObjectMapper with the configured settings.

244

*/

245

public ObjectMapper build();

246

247

/**

248

* Configures property naming strategy.

249

*/

250

public void setPropertyNamingStrategy(PropertyNamingStrategy strategy);

251

252

/**

253

* Configures serialization inclusion.

254

*/

255

public void setSerializationInclusion(JsonInclude.Include inclusion);

256

}

257

```

258

259

**Usage Example:**

260

261

```java

262

@Override

263

public void initialize(Bootstrap<MyConfiguration> bootstrap) {

264

// Configure JSON serialization

265

bootstrap.getObjectMapper()

266

.registerModule(new JavaTimeModule())

267

.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)

268

.setSerializationInclusion(JsonInclude.Include.NON_NULL);

269

}

270

271

// Custom JSON views

272

public class Views {

273

public static class Public {}

274

public static class Internal extends Public {}

275

}

276

277

public class User {

278

@JsonView(Views.Public.class)

279

private String name;

280

281

@JsonView(Views.Internal.class)

282

private String email;

283

284

// getters and setters

285

}

286

287

@GET

288

@JsonView(Views.Public.class)

289

public List<User> getPublicUsers() {

290

return userService.findAll();

291

}

292

```

293

294

### Custom Providers

295

296

Implement custom message body readers and writers for handling specific content types or data formats.

297

298

```java { .api }

299

package javax.ws.rs.ext;

300

301

@Provider

302

@Consumes("text/csv")

303

public interface MessageBodyReader<T> {

304

boolean isReadable(Class<?> type, Type genericType,

305

Annotation[] annotations, MediaType mediaType);

306

307

T readFrom(Class<T> type, Type genericType, Annotation[] annotations,

308

MediaType mediaType, MultivaluedMap<String, String> httpHeaders,

309

InputStream entityStream) throws IOException, WebApplicationException;

310

}

311

312

@Provider

313

@Produces("text/csv")

314

public interface MessageBodyWriter<T> {

315

boolean isWriteable(Class<?> type, Type genericType,

316

Annotation[] annotations, MediaType mediaType);

317

318

void writeTo(T t, Class<?> type, Type genericType,

319

Annotation[] annotations, MediaType mediaType,

320

MultivaluedMap<String, Object> httpHeaders,

321

OutputStream entityStream) throws IOException, WebApplicationException;

322

}

323

```

324

325

## Response Handling

326

327

### Response Types

328

329

Standard JAX-RS response patterns for different HTTP scenarios.

330

331

```java

332

// Simple entity response

333

return user;

334

335

// Response with status code

336

return Response.ok(user).build();

337

return Response.status(201).entity(user).build();

338

339

// Created resource with location header

340

URI location = uriInfo.getAbsolutePathBuilder().path("123").build();

341

return Response.created(location).entity(user).build();

342

343

// No content response

344

return Response.noContent().build();

345

346

// Error responses

347

return Response.status(400).entity(errorMessage).build();

348

return Response.status(404).build();

349

350

// Optional responses

351

Optional<User> user = userService.findById(id);

352

return user.map(Response::ok)

353

.orElse(Response.status(404))

354

.build();

355

```