or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

callbacks.mdcore-annotations.mdenums.mdindex.mdlinks.mdresponses.mdschema-media.mdsecurity.mdserver-info.md

responses.mddocs/

0

# Response Management

1

2

Structured response documentation with status codes, content types, headers, request bodies, and linking between operations. This system provides comprehensive response definitions for REST API operations including success responses, error responses, and complex data flows.

3

4

## Capabilities

5

6

### API Response Definition

7

8

Defines comprehensive API responses with status codes, content, headers, and links.

9

10

```java { .api }

11

/**

12

* Describes API response with comprehensive metadata

13

* Applied to: METHOD, TYPE

14

* Repeatable: Yes

15

*/

16

@ApiResponse(

17

responseCode = "200", // HTTP response code (required)

18

description = "Successful response", // Response description (required)

19

20

content = { // Response content for different media types

21

@Content(

22

mediaType = "application/json",

23

schema = @Schema(implementation = User.class),

24

examples = {@ExampleObject(...)}

25

),

26

@Content(

27

mediaType = "application/xml",

28

schema = @Schema(implementation = User.class)

29

)

30

},

31

32

headers = { // Response headers

33

@Header(

34

name = "X-Rate-Limit-Remaining",

35

description = "Number of requests remaining",

36

schema = @Schema(type = "integer")

37

),

38

@Header(

39

name = "X-Rate-Limit-Reset",

40

description = "Rate limit reset timestamp",

41

schema = @Schema(type = "integer", format = "int64")

42

)

43

},

44

45

links = { // Links to related operations

46

@Link(

47

name = "getUserById",

48

operationId = "getUserById",

49

parameters = @LinkParameter(name = "userId", expression = "$response.body#/id")

50

)

51

},

52

53

extensions = {@Extension(...)}, // Custom extensions

54

ref = "#/components/responses/UserResponse" // Reference to component response

55

)

56

```

57

58

**Usage Examples:**

59

60

```java

61

// Success response with content

62

@GET

63

@Path("/{id}")

64

@Operation(summary = "Get user by ID")

65

@ApiResponse(

66

responseCode = "200",

67

description = "User found successfully",

68

content = @Content(

69

mediaType = "application/json",

70

schema = @Schema(implementation = User.class),

71

examples = @ExampleObject(

72

name = "userExample",

73

value = "{\"id\":123,\"name\":\"John Doe\",\"email\":\"john@example.com\"}"

74

)

75

),

76

headers = {

77

@Header(

78

name = "Last-Modified",

79

description = "Last modification timestamp",

80

schema = @Schema(type = "string", format = "date-time")

81

),

82

@Header(

83

name = "ETag",

84

description = "Entity tag for caching",

85

schema = @Schema(type = "string")

86

)

87

}

88

)

89

@ApiResponse(

90

responseCode = "404",

91

description = "User not found",

92

content = @Content(

93

mediaType = "application/json",

94

schema = @Schema(implementation = ErrorResponse.class)

95

)

96

)

97

public Response getUserById(@PathParam("id") Long id) {}

98

99

// Multiple success responses based on accept header

100

@GET

101

@Operation(summary = "Get user data in multiple formats")

102

@ApiResponse(

103

responseCode = "200",

104

description = "User data",

105

content = {

106

@Content(

107

mediaType = "application/json",

108

schema = @Schema(implementation = User.class)

109

),

110

@Content(

111

mediaType = "application/xml",

112

schema = @Schema(implementation = User.class)

113

),

114

@Content(

115

mediaType = "text/csv",

116

schema = @Schema(type = "string", description = "CSV representation")

117

)

118

}

119

)

120

public Response getUserData(@PathParam("id") Long id) {}

121

122

// Response with pagination headers

123

@GET

124

@Operation(summary = "List users with pagination")

125

@ApiResponse(

126

responseCode = "200",

127

description = "User list retrieved successfully",

128

content = @Content(

129

mediaType = "application/json",

130

schema = @Schema(implementation = UserList.class)

131

),

132

headers = {

133

@Header(

134

name = "X-Total-Count",

135

description = "Total number of users",

136

schema = @Schema(type = "integer")

137

),

138

@Header(

139

name = "X-Page-Number",

140

description = "Current page number",

141

schema = @Schema(type = "integer")

142

),

143

@Header(

144

name = "X-Page-Size",

145

description = "Number of items per page",

146

schema = @Schema(type = "integer")

147

),

148

@Header(

149

name = "Link",

150

description = "Pagination links (next, prev, first, last)",

151

schema = @Schema(type = "string")

152

)

153

}

154

)

155

public Response listUsers(

156

@QueryParam("page") Integer page,

157

@QueryParam("size") Integer size

158

) {}

159

```

160

161

### API Responses Container

162

163

Container for multiple API response definitions on a single operation.

164

165

```java { .api }

166

/**

167

* Container for multiple ApiResponse annotations

168

*/

169

@ApiResponses({

170

@ApiResponse(responseCode = "200", description = "Success", content = @Content(...)),

171

@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(...)),

172

@ApiResponse(responseCode = "401", description = "Unauthorized"),

173

@ApiResponse(responseCode = "403", description = "Forbidden"),

174

@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(...)),

175

@ApiResponse(responseCode = "500", description = "Internal Server Error", content = @Content(...))

176

})

177

```

178

179

**Complete CRUD Response Examples:**

180

181

```java

182

@POST

183

@Operation(summary = "Create new user")

184

@ApiResponses({

185

@ApiResponse(

186

responseCode = "201",

187

description = "User created successfully",

188

content = @Content(

189

mediaType = "application/json",

190

schema = @Schema(implementation = User.class)

191

),

192

headers = {

193

@Header(

194

name = "Location",

195

description = "URL of the created user",

196

schema = @Schema(type = "string", format = "uri")

197

),

198

@Header(

199

name = "X-Request-ID",

200

description = "Request tracking ID",

201

schema = @Schema(type = "string", format = "uuid")

202

)

203

}

204

),

205

@ApiResponse(

206

responseCode = "400",

207

description = "Invalid user data provided",

208

content = @Content(

209

mediaType = "application/json",

210

schema = @Schema(implementation = ValidationError.class)

211

)

212

),

213

@ApiResponse(

214

responseCode = "409",

215

description = "User with this email already exists",

216

content = @Content(

217

mediaType = "application/json",

218

schema = @Schema(implementation = ConflictError.class)

219

)

220

),

221

@ApiResponse(

222

responseCode = "422",

223

description = "Unprocessable entity - validation failed",

224

content = @Content(

225

mediaType = "application/json",

226

schema = @Schema(implementation = ValidationError.class)

227

)

228

)

229

})

230

public Response createUser(@RequestBody CreateUserRequest request) {}

231

232

@PUT

233

@Path("/{id}")

234

@Operation(summary = "Update user")

235

@ApiResponses({

236

@ApiResponse(

237

responseCode = "200",

238

description = "User updated successfully",

239

content = @Content(schema = @Schema(implementation = User.class))

240

),

241

@ApiResponse(

242

responseCode = "204",

243

description = "User updated successfully (no content returned)"

244

),

245

@ApiResponse(responseCode = "400", description = "Invalid update data"),

246

@ApiResponse(responseCode = "404", description = "User not found"),

247

@ApiResponse(responseCode = "409", description = "Update conflict (optimistic locking)")

248

})

249

public Response updateUser(@PathParam("id") Long id, @RequestBody UpdateUserRequest request) {}

250

251

@DELETE

252

@Path("/{id}")

253

@Operation(summary = "Delete user")

254

@ApiResponses({

255

@ApiResponse(responseCode = "204", description = "User deleted successfully"),

256

@ApiResponse(responseCode = "404", description = "User not found"),

257

@ApiResponse(

258

responseCode = "409",

259

description = "Cannot delete user with active dependencies",

260

content = @Content(schema = @Schema(implementation = ConflictError.class))

261

)

262

})

263

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

264

```

265

266

### Request Body Definition

267

268

Defines request body content with schema, examples, and validation requirements.

269

270

```java { .api }

271

/**

272

* Defines request body for operations

273

* Applied to: METHOD, PARAMETER

274

*/

275

@RequestBody(

276

description = "User data for creation", // Request body description

277

required = true, // Whether request body is required

278

content = { // Content for different media types

279

@Content(

280

mediaType = "application/json",

281

schema = @Schema(implementation = CreateUserRequest.class),

282

examples = {

283

@ExampleObject(

284

name = "basicUser",

285

summary = "Basic user creation",

286

value = "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"

287

),

288

@ExampleObject(

289

name = "adminUser",

290

summary = "Admin user creation",

291

value = "{\"name\":\"Admin User\",\"email\":\"admin@example.com\",\"role\":\"ADMIN\"}"

292

)

293

}

294

),

295

@Content(

296

mediaType = "application/xml",

297

schema = @Schema(implementation = CreateUserRequest.class)

298

)

299

},

300

extensions = {@Extension(...)}, // Custom extensions

301

ref = "#/components/requestBodies/CreateUserRequest" // Reference to component

302

)

303

```

304

305

**Usage Examples:**

306

307

```java

308

// JSON request body

309

@POST

310

@Operation(summary = "Create user")

311

@RequestBody(

312

description = "User data",

313

required = true,

314

content = @Content(

315

mediaType = "application/json",

316

schema = @Schema(implementation = CreateUserRequest.class),

317

examples = @ExampleObject(

318

name = "example",

319

value = "{\"name\":\"John\",\"email\":\"john@example.com\",\"age\":30}"

320

)

321

)

322

)

323

public Response createUser(CreateUserRequest request) {}

324

325

// Multiple content types

326

@POST

327

@Path("/upload")

328

@Operation(summary = "Upload user profile")

329

@RequestBody(

330

description = "User profile data",

331

required = true,

332

content = {

333

@Content(

334

mediaType = "application/json",

335

schema = @Schema(implementation = UserProfile.class)

336

),

337

@Content(

338

mediaType = "multipart/form-data",

339

schema = @Schema(implementation = UserProfileForm.class),

340

encoding = {

341

@Encoding(

342

name = "profileImage",

343

contentType = "image/png, image/jpeg",

344

headers = @Header(

345

name = "X-Image-Quality",

346

schema = @Schema(type = "string", allowableValues = {"low", "medium", "high"})

347

)

348

)

349

}

350

),

351

@Content(

352

mediaType = "application/x-www-form-urlencoded",

353

schema = @Schema(implementation = UserProfileForm.class)

354

)

355

}

356

)

357

public Response uploadProfile(UserProfileForm form) {}

358

359

// File upload request body

360

@POST

361

@Path("/documents")

362

@Operation(summary = "Upload document")

363

@RequestBody(

364

description = "Document file with metadata",

365

required = true,

366

content = @Content(

367

mediaType = "multipart/form-data",

368

encoding = {

369

@Encoding(

370

name = "file",

371

contentType = "application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document",

372

headers = {

373

@Header(

374

name = "Content-Disposition",

375

schema = @Schema(type = "string")

376

)

377

}

378

),

379

@Encoding(

380

name = "metadata",

381

contentType = "application/json"

382

)

383

}

384

)

385

)

386

public Response uploadDocument(

387

@FormParam("file") InputStream file,

388

@FormParam("metadata") DocumentMetadata metadata

389

) {}

390

391

// Optional request body

392

@PUT

393

@Path("/{id}/preferences")

394

@Operation(summary = "Update user preferences")

395

@RequestBody(

396

description = "User preferences (optional - missing fields will not be updated)",

397

required = false,

398

content = @Content(

399

mediaType = "application/json",

400

schema = @Schema(implementation = UserPreferences.class)

401

)

402

)

403

public Response updatePreferences(@PathParam("id") Long id, UserPreferences preferences) {}

404

```

405

406

### Response Headers

407

408

Defines headers returned in API responses with schemas and descriptions.

409

410

```java { .api }

411

/**

412

* Defines response header

413

* Applied to: within response definitions

414

*/

415

@Header(

416

name = "X-Rate-Limit-Remaining", // Header name (required)

417

description = "Number of requests remaining in current window", // Description

418

required = false, // Whether header is always present

419

deprecated = false, // Deprecation status

420

explode = Explode.DEFAULT, // Explode array/object values

421

hidden = false, // Hide from documentation

422

schema = @Schema( // Header value schema

423

type = "integer",

424

minimum = "0",

425

example = "42"

426

),

427

array = @ArraySchema(...), // Array schema alternative

428

example = "100", // Example value

429

examples = {@ExampleObject(...)}, // Multiple examples

430

ref = "#/components/headers/RateLimit", // Reference to component header

431

extensions = {@Extension(...)} // Custom extensions

432

)

433

```

434

435

**Common Response Header Patterns:**

436

437

```java

438

// Rate limiting headers

439

@ApiResponse(

440

responseCode = "200",

441

description = "Success with rate limit info",

442

headers = {

443

@Header(

444

name = "X-RateLimit-Limit",

445

description = "Request limit per hour",

446

schema = @Schema(type = "integer", example = "1000")

447

),

448

@Header(

449

name = "X-RateLimit-Remaining",

450

description = "Requests remaining in current window",

451

schema = @Schema(type = "integer", example = "999")

452

),

453

@Header(

454

name = "X-RateLimit-Reset",

455

description = "Time when rate limit resets",

456

schema = @Schema(type = "integer", format = "int64", example = "1640995200")

457

)

458

}

459

)

460

461

// Caching headers

462

@ApiResponse(

463

responseCode = "200",

464

description = "Success with caching headers",

465

headers = {

466

@Header(

467

name = "ETag",

468

description = "Entity tag for caching",

469

schema = @Schema(type = "string", example = "\"abc123\"")

470

),

471

@Header(

472

name = "Last-Modified",

473

description = "Last modification time",

474

schema = @Schema(type = "string", format = "date-time")

475

),

476

@Header(

477

name = "Cache-Control",

478

description = "Cache control directives",

479

schema = @Schema(type = "string", example = "max-age=3600, must-revalidate")

480

)

481

}

482

)

483

484

// CORS headers

485

@ApiResponse(

486

responseCode = "200",

487

description = "Success with CORS headers",

488

headers = {

489

@Header(

490

name = "Access-Control-Allow-Origin",

491

description = "Allowed origins for CORS",

492

schema = @Schema(type = "string", example = "https://example.com")

493

),

494

@Header(

495

name = "Access-Control-Allow-Methods",

496

description = "Allowed HTTP methods",

497

schema = @Schema(type = "string", example = "GET, POST, PUT, DELETE")

498

),

499

@Header(

500

name = "Access-Control-Allow-Headers",

501

description = "Allowed request headers",

502

schema = @Schema(type = "string", example = "Content-Type, Authorization")

503

)

504

}

505

)

506

507

// Location header for created resources

508

@ApiResponse(

509

responseCode = "201",

510

description = "Resource created successfully",

511

headers = @Header(

512

name = "Location",

513

description = "URL of the created resource",

514

required = true,

515

schema = @Schema(type = "string", format = "uri", example = "https://api.example.com/users/123")

516

)

517

)

518

519

// Content disposition for file downloads

520

@ApiResponse(

521

responseCode = "200",

522

description = "File download",

523

content = @Content(

524

mediaType = "application/octet-stream",

525

schema = @Schema(type = "string", format = "binary")

526

),

527

headers = {

528

@Header(

529

name = "Content-Disposition",

530

description = "File download disposition",

531

schema = @Schema(type = "string", example = "attachment; filename=\"report.pdf\"")

532

),

533

@Header(

534

name = "Content-Length",

535

description = "File size in bytes",

536

schema = @Schema(type = "integer", format = "int64")

537

)

538

}

539

)

540

```

541

542

### Operation Links

543

544

Defines links between operations to describe workflows and related actions.

545

546

```java { .api }

547

/**

548

* Defines link to related operation

549

* Applied to: within response definitions

550

*/

551

@Link(

552

name = "getUserById", // Link name (required)

553

operationRef = "#/paths/~1users~1{userId}/get", // Reference to operation

554

operationId = "getUserById", // Operation ID reference

555

parameters = { // Parameters to pass to linked operation

556

@LinkParameter(name = "userId", expression = "$response.body#/id")

557

},

558

requestBody = "$response.body#/userDetails", // Request body for linked operation

559

description = "Get the created user details", // Link description

560

server = @Server(...), // Alternative server for link

561

extensions = {@Extension(...)}, // Custom extensions

562

ref = "#/components/links/GetUserById" // Reference to component link

563

)

564

565

/**

566

* Link parameter definition

567

*/

568

@LinkParameter(

569

name = "userId", // Parameter name (required)

570

expression = "$response.body#/id" // Expression to get parameter value

571

)

572

```

573

574

**Link Expression Examples:**

575

576

```java

577

// Response body field

578

@LinkParameter(name = "userId", expression = "$response.body#/id")

579

580

// Response header value

581

@LinkParameter(name = "etag", expression = "$response.header.ETag")

582

583

// Query parameter from current request

584

@LinkParameter(name = "include", expression = "$request.query.include")

585

586

// Path parameter from current request

587

@LinkParameter(name = "version", expression = "$request.path.version")

588

589

// Constant value

590

@LinkParameter(name = "format", expression = "json")

591

```

592

593

**Usage Examples:**

594

595

```java

596

@POST

597

@Operation(summary = "Create user")

598

@ApiResponse(

599

responseCode = "201",

600

description = "User created successfully",

601

content = @Content(schema = @Schema(implementation = User.class)),

602

links = {

603

@Link(

604

name = "GetUserById",

605

description = "Get the created user",

606

operationId = "getUserById",

607

parameters = @LinkParameter(name = "id", expression = "$response.body#/id")

608

),

609

@Link(

610

name = "UpdateUser",

611

description = "Update the created user",

612

operationId = "updateUser",

613

parameters = @LinkParameter(name = "id", expression = "$response.body#/id")

614

),

615

@Link(

616

name = "DeleteUser",

617

description = "Delete the created user",

618

operationId = "deleteUser",

619

parameters = @LinkParameter(name = "id", expression = "$response.body#/id")

620

)

621

}

622

)

623

public Response createUser(@RequestBody CreateUserRequest request) {}

624

625

@GET

626

@Path("/{id}")

627

@Operation(operationId = "getUserById", summary = "Get user by ID")

628

@ApiResponse(

629

responseCode = "200",

630

description = "User retrieved successfully",

631

content = @Content(schema = @Schema(implementation = User.class)),

632

links = {

633

@Link(

634

name = "GetUserPosts",

635

description = "Get posts by this user",

636

operationId = "getPostsByUserId",

637

parameters = @LinkParameter(name = "userId", expression = "$response.body#/id")

638

),

639

@Link(

640

name = "GetUserProfile",

641

description = "Get user profile",

642

operationId = "getUserProfile",

643

parameters = @LinkParameter(name = "userId", expression = "$response.body#/id")

644

)

645

}

646

)

647

public Response getUserById(@PathParam("id") Long id) {}

648

```

649

650

## Error Response Patterns

651

652

### Standard Error Responses

653

654

```java

655

// Standard error schema

656

@Schema(description = "Standard error response")

657

public class ErrorResponse {

658

@Schema(description = "Error code", example = "USER_NOT_FOUND")

659

private String code;

660

661

@Schema(description = "Human-readable error message", example = "User with ID 123 not found")

662

private String message;

663

664

@Schema(description = "Request timestamp", format = "date-time")

665

private String timestamp;

666

667

@Schema(description = "Request tracking ID", format = "uuid")

668

private String requestId;

669

}

670

671

// Validation error schema

672

@Schema(description = "Validation error with field details")

673

public class ValidationError extends ErrorResponse {

674

@Schema(description = "Field-specific validation errors")

675

private List<FieldError> fieldErrors;

676

}

677

678

@Schema(description = "Individual field validation error")

679

public class FieldError {

680

@Schema(description = "Field name", example = "email")

681

private String field;

682

683

@Schema(description = "Invalid value", example = "not-an-email")

684

private String rejectedValue;

685

686

@Schema(description = "Validation message", example = "must be a valid email address")

687

private String message;

688

}

689

```

690

691

### Complete Error Response Set

692

693

```java

694

@ApiResponses({

695

@ApiResponse(responseCode = "200", description = "Success"),

696

@ApiResponse(

697

responseCode = "400",

698

description = "Bad Request - Invalid input data",

699

content = @Content(

700

mediaType = "application/json",

701

schema = @Schema(implementation = ValidationError.class),

702

examples = @ExampleObject(

703

name = "validationError",

704

value = "{\"code\":\"VALIDATION_ERROR\",\"message\":\"Invalid input\",\"fieldErrors\":[{\"field\":\"email\",\"message\":\"Invalid email format\"}]}"

705

)

706

)

707

),

708

@ApiResponse(

709

responseCode = "401",

710

description = "Unauthorized - Authentication required",

711

content = @Content(schema = @Schema(implementation = ErrorResponse.class))

712

),

713

@ApiResponse(

714

responseCode = "403",

715

description = "Forbidden - Insufficient permissions",

716

content = @Content(schema = @Schema(implementation = ErrorResponse.class))

717

),

718

@ApiResponse(

719

responseCode = "404",

720

description = "Not Found - Resource does not exist",

721

content = @Content(schema = @Schema(implementation = ErrorResponse.class))

722

),

723

@ApiResponse(

724

responseCode = "429",

725

description = "Too Many Requests - Rate limit exceeded",

726

content = @Content(schema = @Schema(implementation = ErrorResponse.class)),

727

headers = {

728

@Header(name = "Retry-After", schema = @Schema(type = "integer", description = "Seconds to wait"))

729

}

730

),

731

@ApiResponse(

732

responseCode = "500",

733

description = "Internal Server Error",

734

content = @Content(schema = @Schema(implementation = ErrorResponse.class))

735

)

736

})

737

```