or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-api.mdcore-types.mdextensions.mdindex.mdresource-endpoints.mdserver-container.mdserver-sent-events.md

resource-endpoints.mddocs/

0

# Resource Endpoints

1

2

The resource endpoints capabilities provide the core annotations and mechanisms for defining REST endpoints, mapping HTTP methods, and injecting request parameters into Java methods.

3

4

## Core Imports

5

6

```java

7

import javax.ws.rs.Path;

8

import javax.ws.rs.ApplicationPath;

9

import javax.ws.rs.GET;

10

import javax.ws.rs.POST;

11

import javax.ws.rs.PUT;

12

import javax.ws.rs.DELETE;

13

import javax.ws.rs.HEAD;

14

import javax.ws.rs.OPTIONS;

15

import javax.ws.rs.PATCH;

16

17

import javax.ws.rs.PathParam;

18

import javax.ws.rs.QueryParam;

19

import javax.ws.rs.HeaderParam;

20

import javax.ws.rs.CookieParam;

21

import javax.ws.rs.FormParam;

22

import javax.ws.rs.MatrixParam;

23

import javax.ws.rs.BeanParam;

24

import javax.ws.rs.DefaultValue;

25

26

import javax.ws.rs.Consumes;

27

import javax.ws.rs.Produces;

28

import javax.ws.rs.Encoded;

29

30

import javax.ws.rs.core.MediaType;

31

import javax.ws.rs.core.Response;

32

import javax.ws.rs.core.Context;

33

import javax.ws.rs.core.UriInfo;

34

import javax.ws.rs.core.HttpHeaders;

35

import javax.ws.rs.core.SecurityContext;

36

import javax.ws.rs.core.Request;

37

```

38

39

## Path Definition

40

41

### @Path Annotation

42

43

Identifies the URI path template for resources and sub-resources.

44

45

```java { .api }

46

@Target({ElementType.TYPE, ElementType.METHOD})

47

@Retention(RetentionPolicy.RUNTIME)

48

@Documented

49

public @interface Path {

50

String value();

51

}

52

```

53

54

**Usage Example:**

55

56

```java

57

@Path("/users")

58

public class UserResource {

59

60

@GET

61

@Path("/{id}")

62

public Response getUser(@PathParam("id") String userId) {

63

// Implementation

64

return Response.ok().build();

65

}

66

67

@GET

68

@Path("/{id}/orders/{orderId}")

69

public Response getUserOrder(@PathParam("id") String userId,

70

@PathParam("orderId") String orderId) {

71

// Nested path parameters

72

return Response.ok().build();

73

}

74

}

75

```

76

77

### @ApplicationPath Annotation

78

79

Identifies the application path that serves as the base URI for all resource URIs provided by @Path annotations.

80

81

```java { .api }

82

@Target({ElementType.TYPE})

83

@Retention(RetentionPolicy.RUNTIME)

84

@Documented

85

public @interface ApplicationPath {

86

String value();

87

}

88

```

89

90

**Usage Example:**

91

92

```java

93

@ApplicationPath("/api/v1")

94

public class MyApplication extends Application {

95

// Optional: configure resource classes, singletons, providers

96

@Override

97

public Set<Class<?>> getClasses() {

98

Set<Class<?>> classes = new HashSet<>();

99

classes.add(UserResource.class);

100

classes.add(OrderResource.class);

101

return classes;

102

}

103

}

104

```

105

106

## HTTP Method Annotations

107

108

### Standard HTTP Methods

109

110

```java { .api }

111

@Target({ElementType.METHOD})

112

@Retention(RetentionPolicy.RUNTIME)

113

@HttpMethod("GET")

114

@Documented

115

public @interface GET {

116

}

117

118

@Target({ElementType.METHOD})

119

@Retention(RetentionPolicy.RUNTIME)

120

@HttpMethod("POST")

121

@Documented

122

public @interface POST {

123

}

124

125

@Target({ElementType.METHOD})

126

@Retention(RetentionPolicy.RUNTIME)

127

@HttpMethod("PUT")

128

@Documented

129

public @interface PUT {

130

}

131

132

@Target({ElementType.METHOD})

133

@Retention(RetentionPolicy.RUNTIME)

134

@HttpMethod("DELETE")

135

@Documented

136

public @interface DELETE {

137

}

138

139

@Target({ElementType.METHOD})

140

@Retention(RetentionPolicy.RUNTIME)

141

@HttpMethod("HEAD")

142

@Documented

143

public @interface HEAD {

144

}

145

146

@Target({ElementType.METHOD})

147

@Retention(RetentionPolicy.RUNTIME)

148

@HttpMethod("OPTIONS")

149

@Documented

150

public @interface OPTIONS {

151

}

152

153

@Target({ElementType.METHOD})

154

@Retention(RetentionPolicy.RUNTIME)

155

@HttpMethod("PATCH")

156

@Documented

157

public @interface PATCH {

158

}

159

```

160

161

**Usage Example:**

162

163

```java

164

@Path("/products")

165

public class ProductResource {

166

167

@GET

168

public List<Product> getAllProducts() {

169

return productService.findAll();

170

}

171

172

@POST

173

public Response createProduct(Product product) {

174

Product created = productService.save(product);

175

return Response.status(Response.Status.CREATED).entity(created).build();

176

}

177

178

@PUT

179

@Path("/{id}")

180

public Response updateProduct(@PathParam("id") String id, Product product) {

181

Product updated = productService.update(id, product);

182

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

183

}

184

185

@DELETE

186

@Path("/{id}")

187

public Response deleteProduct(@PathParam("id") String id) {

188

productService.delete(id);

189

return Response.noContent().build();

190

}

191

192

@PATCH

193

@Path("/{id}")

194

public Response patchProduct(@PathParam("id") String id,

195

Map<String, Object> updates) {

196

Product patched = productService.patch(id, updates);

197

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

198

}

199

}

200

```

201

202

### Custom HTTP Methods

203

204

```java { .api }

205

@Target({ElementType.ANNOTATION_TYPE})

206

@Retention(RetentionPolicy.RUNTIME)

207

@Documented

208

public @interface HttpMethod {

209

String value();

210

}

211

```

212

213

**Usage Example:**

214

215

```java

216

// Define custom HTTP method annotation

217

@Target({ElementType.METHOD})

218

@Retention(RetentionPolicy.RUNTIME)

219

@HttpMethod("PURGE")

220

@Documented

221

public @interface PURGE {

222

}

223

224

// Use custom method

225

@Path("/cache")

226

public class CacheResource {

227

228

@PURGE

229

@Path("/{key}")

230

public Response purgeCache(@PathParam("key") String cacheKey) {

231

cacheService.purge(cacheKey);

232

return Response.noContent().build();

233

}

234

}

235

```

236

237

## Parameter Injection Annotations

238

239

### Path Parameters

240

241

```java { .api }

242

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

243

@Retention(RetentionPolicy.RUNTIME)

244

@Documented

245

public @interface PathParam {

246

String value();

247

}

248

```

249

250

### Query Parameters

251

252

```java { .api }

253

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

254

@Retention(RetentionPolicy.RUNTIME)

255

@Documented

256

public @interface QueryParam {

257

String value();

258

}

259

```

260

261

### Header Parameters

262

263

```java { .api }

264

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

265

@Retention(RetentionPolicy.RUNTIME)

266

@Documented

267

public @interface HeaderParam {

268

String value();

269

}

270

```

271

272

### Cookie Parameters

273

274

```java { .api }

275

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

276

@Retention(RetentionPolicy.RUNTIME)

277

@Documented

278

public @interface CookieParam {

279

String value();

280

}

281

```

282

283

### Form Parameters

284

285

```java { .api }

286

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

287

@Retention(RetentionPolicy.RUNTIME)

288

@Documented

289

public @interface FormParam {

290

String value();

291

}

292

```

293

294

### Matrix Parameters

295

296

```java { .api }

297

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

298

@Retention(RetentionPolicy.RUNTIME)

299

@Documented

300

public @interface MatrixParam {

301

String value();

302

}

303

```

304

305

### Bean Parameters

306

307

```java { .api }

308

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

309

@Retention(RetentionPolicy.RUNTIME)

310

@Documented

311

public @interface BeanParam {

312

}

313

```

314

315

**Parameter Injection Usage Examples:**

316

317

```java

318

@Path("/search")

319

public class SearchResource {

320

321

@GET

322

@Path("/{category}")

323

public Response search(@PathParam("category") String category,

324

@QueryParam("q") String query,

325

@QueryParam("limit") @DefaultValue("10") int limit,

326

@QueryParam("offset") @DefaultValue("0") int offset,

327

@HeaderParam("Accept-Language") String language,

328

@HeaderParam("User-Agent") String userAgent,

329

@CookieParam("sessionId") String sessionId) {

330

331

SearchRequest request = new SearchRequest(category, query, limit, offset);

332

request.setLanguage(language);

333

request.setUserAgent(userAgent);

334

request.setSessionId(sessionId);

335

336

SearchResults results = searchService.search(request);

337

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

338

}

339

340

// Matrix parameters example: /products;color=red;size=large

341

@GET

342

@Path("/products")

343

public Response findProducts(@MatrixParam("color") String color,

344

@MatrixParam("size") String size,

345

@MatrixParam("brand") List<String> brands) {

346

ProductFilter filter = new ProductFilter(color, size, brands);

347

List<Product> products = productService.findByFilter(filter);

348

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

349

}

350

351

// Form parameters for POST requests

352

@POST

353

@Path("/contact")

354

@Consumes(MediaType.APPLICATION_FORM_URLENCODED)

355

public Response submitContactForm(@FormParam("name") String name,

356

@FormParam("email") String email,

357

@FormParam("message") String message,

358

@FormParam("subscribe") boolean subscribe) {

359

360

ContactSubmission submission = new ContactSubmission(name, email, message, subscribe);

361

contactService.submit(submission);

362

return Response.ok().build();

363

}

364

}

365

```

366

367

### Bean Parameter Example

368

369

```java

370

// Parameter aggregator class

371

public class SearchParams {

372

@QueryParam("q")

373

private String query;

374

375

@QueryParam("limit")

376

@DefaultValue("10")

377

private int limit;

378

379

@QueryParam("offset")

380

@DefaultValue("0")

381

private int offset;

382

383

@HeaderParam("Accept-Language")

384

private String language;

385

386

// Getters and setters...

387

}

388

389

@Path("/items")

390

public class ItemResource {

391

392

@GET

393

public Response searchItems(@BeanParam SearchParams params) {

394

List<Item> items = itemService.search(params);

395

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

396

}

397

}

398

```

399

400

### Default Values

401

402

```java { .api }

403

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

404

@Retention(RetentionPolicy.RUNTIME)

405

@Documented

406

public @interface DefaultValue {

407

String value();

408

}

409

```

410

411

## Content Negotiation

412

413

### @Consumes Annotation

414

415

Specifies the media types that a resource method can accept.

416

417

```java { .api }

418

@Target({ElementType.TYPE, ElementType.METHOD})

419

@Retention(RetentionPolicy.RUNTIME)

420

@Documented

421

public @interface Consumes {

422

String[] value() default {"*/*"};

423

}

424

```

425

426

### @Produces Annotation

427

428

Specifies the media types that a resource method can produce.

429

430

```java { .api }

431

@Target({ElementType.TYPE, ElementType.METHOD})

432

@Retention(RetentionPolicy.RUNTIME)

433

@Documented

434

public @interface Produces {

435

String[] value() default {"*/*"};

436

}

437

```

438

439

**Content Negotiation Examples:**

440

441

```java

442

@Path("/api/v1/users")

443

@Produces(MediaType.APPLICATION_JSON) // Default for all methods in class

444

public class UserApiResource {

445

446

@GET

447

@Path("/{id}")

448

public User getUser(@PathParam("id") String id) {

449

// Returns JSON by default

450

return userService.findById(id);

451

}

452

453

@GET

454

@Path("/{id}")

455

@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})

456

public User getUserWithXml(@PathParam("id") String id) {

457

// Can return either XML or JSON based on Accept header

458

return userService.findById(id);

459

}

460

461

@POST

462

@Consumes(MediaType.APPLICATION_JSON)

463

public Response createUser(User user) {

464

// Only accepts JSON input

465

User created = userService.create(user);

466

return Response.status(Response.Status.CREATED).entity(created).build();

467

}

468

469

@PUT

470

@Path("/{id}")

471

@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})

472

@Produces(MediaType.APPLICATION_JSON)

473

public Response updateUser(@PathParam("id") String id, User user) {

474

// Accepts both JSON and XML input, returns JSON

475

User updated = userService.update(id, user);

476

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

477

}

478

479

@POST

480

@Path("/upload")

481

@Consumes(MediaType.MULTIPART_FORM_DATA)

482

public Response uploadUserAvatar(@PathParam("id") String userId,

483

@FormParam("file") InputStream fileStream,

484

@FormParam("filename") String filename) {

485

avatarService.upload(userId, fileStream, filename);

486

return Response.ok().build();

487

}

488

}

489

```

490

491

## Encoding Control

492

493

### @Encoded Annotation

494

495

Disables automatic URI decoding for parameter values.

496

497

```java { .api }

498

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD,

499

ElementType.CONSTRUCTOR, ElementType.TYPE})

500

@Retention(RetentionPolicy.RUNTIME)

501

@Documented

502

public @interface Encoded {

503

}

504

```

505

506

**Usage Example:**

507

508

```java

509

@Path("/files")

510

public class FileResource {

511

512

@GET

513

@Path("/{filename}")

514

public Response getFile(@PathParam("filename") @Encoded String encodedFilename,

515

@QueryParam("path") @Encoded String encodedPath) {

516

// Parameters remain URL-encoded, useful for filenames with special chars

517

String actualFilename = URLDecoder.decode(encodedFilename, "UTF-8");

518

String actualPath = URLDecoder.decode(encodedPath, "UTF-8");

519

520

File file = fileService.getFile(actualPath, actualFilename);

521

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

522

}

523

}

524

```

525

526

## Context Injection

527

528

JAX-RS provides several context objects that can be injected into resource methods:

529

530

```java { .api }

531

@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})

532

@Retention(RetentionPolicy.RUNTIME)

533

@Documented

534

public @interface Context {

535

}

536

```

537

538

**Common Context Types:**

539

540

```java

541

@Path("/info")

542

public class InfoResource {

543

544

@GET

545

public Response getRequestInfo(@Context UriInfo uriInfo,

546

@Context HttpHeaders headers,

547

@Context SecurityContext securityContext) {

548

549

Map<String, Object> info = new HashMap<>();

550

info.put("requestUri", uriInfo.getRequestUri().toString());

551

info.put("baseUri", uriInfo.getBaseUri().toString());

552

info.put("pathParameters", uriInfo.getPathParameters());

553

info.put("queryParameters", uriInfo.getQueryParameters());

554

info.put("userPrincipal", securityContext.getUserPrincipal());

555

info.put("acceptHeader", headers.getHeaderString("Accept"));

556

557

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

558

}

559

}

560

```

561

562

## Types

563

564

### Media Type Constants

565

566

```java { .api }

567

public class MediaType {

568

public static final String APPLICATION_JSON = "application/json";

569

public static final String APPLICATION_XML = "application/xml";

570

public static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded";

571

public static final String MULTIPART_FORM_DATA = "multipart/form-data";

572

public static final String TEXT_PLAIN = "text/plain";

573

public static final String TEXT_HTML = "text/html";

574

public static final String TEXT_XML = "text/xml";

575

public static final String WILDCARD = "*/*";

576

577

public static final MediaType APPLICATION_JSON_TYPE = new MediaType("application", "json");

578

public static final MediaType APPLICATION_XML_TYPE = new MediaType("application", "xml");

579

public static final MediaType TEXT_PLAIN_TYPE = new MediaType("text", "plain");

580

public static final MediaType WILDCARD_TYPE = new MediaType("*", "*");

581

}

582

```