or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-api.mddocumentation.mdextensions.mdindex.mdmodels.mdparameters.mdresponses.mdsecurity.md

responses.mddocs/

0

# Response Documentation

1

2

Annotations for documenting API responses, status codes, and response headers. These annotations provide detailed metadata about what clients can expect when calling API endpoints, including success and error scenarios.

3

4

## Capabilities

5

6

### @ApiResponse Annotation

7

8

Documents a single response from an operation, including the response code, message, and return type.

9

10

```java { .api }

11

/**

12

* Documents a single response from an operation

13

* Target: METHOD, TYPE

14

* Retention: RUNTIME

15

*/

16

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

17

@Retention(RetentionPolicy.RUNTIME)

18

@interface ApiResponse {

19

/**

20

* Response code (HTTP status code)

21

* REQUIRED ATTRIBUTE

22

* Should use formal HTTP Status Code definitions

23

*/

24

int code();

25

26

/**

27

* Human-readable response message

28

* REQUIRED ATTRIBUTE

29

* Brief description of what this response means

30

*/

31

String message();

32

33

/**

34

* Optional response class

35

* Describes the type of response body

36

* Default Void.class means no response body

37

*/

38

Class<?> response() default Void.class;

39

40

/**

41

* Specifies a reference to response type definition

42

* Can be local or remote reference

43

* Overrides response() class if specified

44

*/

45

String reference() default "";

46

47

/**

48

* List of possible headers for this response

49

*/

50

ResponseHeader[] responseHeaders() default @ResponseHeader(name = "", response = Void.class);

51

52

/**

53

* Declares container wrapping the response

54

* Valid values: "List", "Set", "Map"

55

* Other values are ignored

56

*/

57

String responseContainer() default "";

58

}

59

```

60

61

**Usage Examples:**

62

63

```java

64

// Single response documentation

65

@ApiResponse(code = 200, message = "User found", response = User.class)

66

@GET

67

@Path("/{id}")

68

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

69

// implementation

70

}

71

72

// Response with headers

73

@ApiResponse(

74

code = 201,

75

message = "User created successfully",

76

response = User.class,

77

responseHeaders = {

78

@ResponseHeader(

79

name = "Location",

80

description = "URL of the created user",

81

response = String.class

82

)

83

}

84

)

85

@POST

86

public Response createUser(User user) {

87

// implementation

88

}

89

90

// Collection response

91

@ApiResponse(

92

code = 200,

93

message = "Users retrieved successfully",

94

response = User.class,

95

responseContainer = "List"

96

)

97

@GET

98

public List<User> getAllUsers() {

99

// implementation

100

}

101

```

102

103

### @ApiResponses Annotation

104

105

Container annotation for documenting multiple possible responses from a single operation.

106

107

```java { .api }

108

/**

109

* Container for multiple @ApiResponse annotations

110

* Target: ANNOTATION_TYPE, METHOD, TYPE

111

* Retention: RUNTIME

112

*/

113

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

114

@Retention(RetentionPolicy.RUNTIME)

115

@interface ApiResponses {

116

/** Array of response definitions */

117

ApiResponse[] value();

118

}

119

```

120

121

**Usage Examples:**

122

123

```java

124

// Multiple response scenarios

125

@ApiResponses({

126

@ApiResponse(code = 200, message = "User found", response = User.class),

127

@ApiResponse(code = 404, message = "User not found"),

128

@ApiResponse(code = 500, message = "Internal server error")

129

})

130

@GET

131

@Path("/{id}")

132

public Response getUser(@PathParam("id") Long id) {

133

// implementation

134

}

135

136

// CRUD operation with full response documentation

137

@ApiResponses({

138

@ApiResponse(

139

code = 201,

140

message = "User created successfully",

141

response = User.class,

142

responseHeaders = @ResponseHeader(name = "Location", response = String.class)

143

),

144

@ApiResponse(code = 400, message = "Invalid user data", response = ErrorResponse.class),

145

@ApiResponse(code = 409, message = "User already exists", response = ErrorResponse.class),

146

@ApiResponse(code = 500, message = "Internal server error", response = ErrorResponse.class)

147

})

148

@POST

149

public Response createUser(User user) {

150

// implementation

151

}

152

153

// Search operation with various outcomes

154

@ApiResponses({

155

@ApiResponse(

156

code = 200,

157

message = "Search completed successfully",

158

response = User.class,

159

responseContainer = "List"

160

),

161

@ApiResponse(code = 204, message = "No users found matching criteria"),

162

@ApiResponse(code = 400, message = "Invalid search parameters", response = ErrorResponse.class),

163

@ApiResponse(code = 429, message = "Rate limit exceeded",

164

responseHeaders = @ResponseHeader(name = "Retry-After", response = Integer.class))

165

})

166

@GET

167

@Path("/search")

168

public Response searchUsers(

169

@QueryParam("q") String query,

170

@QueryParam("limit") Integer limit

171

) {

172

// implementation

173

}

174

```

175

176

### @ResponseHeader Annotation

177

178

Documents headers that may be returned with a response.

179

180

```java { .api }

181

/**

182

* Documents a response header

183

* Target: ANNOTATION_TYPE (used within other annotations)

184

* Retention: RUNTIME

185

*/

186

@Target(ElementType.ANNOTATION_TYPE)

187

@Retention(RetentionPolicy.RUNTIME)

188

@interface ResponseHeader {

189

/**

190

* Name of the response header

191

* REQUIRED ATTRIBUTE

192

*/

193

String name();

194

195

/** Description of the header */

196

String description() default "";

197

198

/**

199

* Response type/class for the header value

200

* REQUIRED ATTRIBUTE

201

*/

202

Class<?> response();

203

204

/**

205

* Container type for the header if it contains multiple values

206

* Valid values: "List", "Set", "Map"

207

*/

208

String responseContainer() default "";

209

}

210

```

211

212

**Usage Examples:**

213

214

```java

215

// Authentication response with token in header

216

@ApiResponse(

217

code = 200,

218

message = "Login successful",

219

response = User.class,

220

responseHeaders = {

221

@ResponseHeader(

222

name = "Authorization",

223

description = "JWT token for subsequent requests",

224

response = String.class

225

),

226

@ResponseHeader(

227

name = "X-Token-Expires",

228

description = "Token expiration timestamp",

229

response = Long.class

230

)

231

}

232

)

233

@POST

234

@Path("/login")

235

public Response login(LoginRequest request) {

236

// implementation

237

}

238

239

// File download with metadata headers

240

@ApiResponse(

241

code = 200,

242

message = "File downloaded successfully",

243

responseHeaders = {

244

@ResponseHeader(

245

name = "Content-Type",

246

description = "MIME type of the file",

247

response = String.class

248

),

249

@ResponseHeader(

250

name = "Content-Length",

251

description = "Size of file in bytes",

252

response = Long.class

253

),

254

@ResponseHeader(

255

name = "Content-Disposition",

256

description = "Attachment filename",

257

response = String.class

258

),

259

@ResponseHeader(

260

name = "Last-Modified",

261

description = "File modification timestamp",

262

response = String.class

263

)

264

}

265

)

266

@GET

267

@Path("/files/{id}/download")

268

public Response downloadFile(@PathParam("id") String fileId) {

269

// implementation

270

}

271

272

// Pagination headers

273

@ApiResponse(

274

code = 200,

275

message = "Page retrieved successfully",

276

response = User.class,

277

responseContainer = "List",

278

responseHeaders = {

279

@ResponseHeader(

280

name = "X-Total-Count",

281

description = "Total number of items available",

282

response = Integer.class

283

),

284

@ResponseHeader(

285

name = "X-Page-Count",

286

description = "Total number of pages",

287

response = Integer.class

288

),

289

@ResponseHeader(

290

name = "Link",

291

description = "Links to first, last, next, and previous pages",

292

response = String.class

293

)

294

}

295

)

296

@GET

297

public Response getUsers(

298

@QueryParam("page") @DefaultValue("1") Integer page,

299

@QueryParam("size") @DefaultValue("20") Integer size

300

) {

301

// implementation

302

}

303

```

304

305

### Common Response Patterns

306

307

#### REST CRUD Operations

308

309

```java

310

@Path("/users")

311

public class UserController {

312

313

// GET collection

314

@ApiResponses({

315

@ApiResponse(

316

code = 200,

317

message = "Users retrieved successfully",

318

response = User.class,

319

responseContainer = "List",

320

responseHeaders = @ResponseHeader(name = "X-Total-Count", response = Integer.class)

321

),

322

@ApiResponse(code = 204, message = "No users found")

323

})

324

@GET

325

public Response getAllUsers() {

326

// implementation

327

}

328

329

// GET single resource

330

@ApiResponses({

331

@ApiResponse(code = 200, message = "User found", response = User.class),

332

@ApiResponse(code = 404, message = "User not found", response = ErrorResponse.class)

333

})

334

@GET

335

@Path("/{id}")

336

public Response getUser(@PathParam("id") Long id) {

337

// implementation

338

}

339

340

// POST create

341

@ApiResponses({

342

@ApiResponse(

343

code = 201,

344

message = "User created successfully",

345

response = User.class,

346

responseHeaders = @ResponseHeader(name = "Location", response = String.class)

347

),

348

@ApiResponse(code = 400, message = "Invalid user data", response = ErrorResponse.class),

349

@ApiResponse(code = 409, message = "User already exists", response = ErrorResponse.class)

350

})

351

@POST

352

public Response createUser(User user) {

353

// implementation

354

}

355

356

// PUT update

357

@ApiResponses({

358

@ApiResponse(code = 200, message = "User updated successfully", response = User.class),

359

@ApiResponse(code = 404, message = "User not found", response = ErrorResponse.class),

360

@ApiResponse(code = 400, message = "Invalid user data", response = ErrorResponse.class)

361

})

362

@PUT

363

@Path("/{id}")

364

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

365

// implementation

366

}

367

368

// DELETE

369

@ApiResponses({

370

@ApiResponse(code = 204, message = "User deleted successfully"),

371

@ApiResponse(code = 404, message = "User not found", response = ErrorResponse.class),

372

@ApiResponse(code = 409, message = "Cannot delete user with active dependencies", response = ErrorResponse.class)

373

})

374

@DELETE

375

@Path("/{id}")

376

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

377

// implementation

378

}

379

}

380

```

381

382

#### Error Response Models

383

384

```java

385

@ApiModel(description = "Standard error response")

386

public class ErrorResponse {

387

388

@ApiModelProperty(value = "Error code", required = true, example = "VALIDATION_ERROR")

389

private String code;

390

391

@ApiModelProperty(value = "Human-readable error message", required = true, example = "Invalid input data")

392

private String message;

393

394

@ApiModelProperty(value = "Request timestamp", example = "2023-01-15T10:30:00Z")

395

private LocalDateTime timestamp;

396

397

@ApiModelProperty(value = "Request path", example = "/api/users")

398

private String path;

399

400

@ApiModelProperty(value = "Validation errors")

401

private List<FieldError> fieldErrors;

402

}

403

404

@ApiModel(description = "Field validation error")

405

public class FieldError {

406

407

@ApiModelProperty(value = "Field name", example = "email")

408

private String field;

409

410

@ApiModelProperty(value = "Rejected value", example = "invalid-email")

411

private Object rejectedValue;

412

413

@ApiModelProperty(value = "Error message", example = "Must be a valid email address")

414

private String message;

415

}

416

```

417

418

#### Async and Long-Running Operations

419

420

```java

421

// Async operation initiation

422

@ApiResponses({

423

@ApiResponse(

424

code = 202,

425

message = "Processing started",

426

response = JobResponse.class,

427

responseHeaders = @ResponseHeader(name = "Location", description = "Job status URL", response = String.class)

428

),

429

@ApiResponse(code = 400, message = "Invalid request", response = ErrorResponse.class)

430

})

431

@POST

432

@Path("/bulk-import")

433

public Response startBulkImport(BulkImportRequest request) {

434

// implementation

435

}

436

437

// Job status checking

438

@ApiResponses({

439

@ApiResponse(code = 200, message = "Job status retrieved", response = JobStatus.class),

440

@ApiResponse(code = 404, message = "Job not found", response = ErrorResponse.class)

441

})

442

@GET

443

@Path("/jobs/{jobId}")

444

public Response getJobStatus(@PathParam("jobId") String jobId) {

445

// implementation

446

}

447

448

@ApiModel(description = "Background job response")

449

public class JobResponse {

450

451

@ApiModelProperty(value = "Job identifier", example = "job-12345")

452

private String jobId;

453

454

@ApiModelProperty(value = "Job status URL", example = "/api/jobs/job-12345")

455

private String statusUrl;

456

457

@ApiModelProperty(value = "Estimated completion time", example = "2023-01-15T11:00:00Z")

458

private LocalDateTime estimatedCompletion;

459

}

460

```

461

462

### File Operations

463

464

```java

465

// File upload

466

@ApiResponses({

467

@ApiResponse(

468

code = 201,

469

message = "File uploaded successfully",

470

response = FileInfo.class,

471

responseHeaders = {

472

@ResponseHeader(name = "Location", description = "File URL", response = String.class),

473

@ResponseHeader(name = "ETag", description = "File hash", response = String.class)

474

}

475

),

476

@ApiResponse(code = 400, message = "Invalid file", response = ErrorResponse.class),

477

@ApiResponse(code = 413, message = "File too large", response = ErrorResponse.class),

478

@ApiResponse(code = 415, message = "Unsupported file type", response = ErrorResponse.class)

479

})

480

@POST

481

@Path("/upload")

482

@Consumes(MediaType.MULTIPART_FORM_DATA)

483

public Response uploadFile(

484

@FormDataParam("file") InputStream fileInputStream,

485

@FormDataParam("file") FormDataContentDisposition fileDetail

486

) {

487

// implementation

488

}

489

490

// File download

491

@ApiResponses({

492

@ApiResponse(

493

code = 200,

494

message = "File content",

495

responseHeaders = {

496

@ResponseHeader(name = "Content-Type", response = String.class),

497

@ResponseHeader(name = "Content-Length", response = Long.class),

498

@ResponseHeader(name = "Content-Disposition", response = String.class)

499

}

500

),

501

@ApiResponse(code = 404, message = "File not found", response = ErrorResponse.class),

502

@ApiResponse(code = 403, message = "Access denied", response = ErrorResponse.class)

503

})

504

@GET

505

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

506

public Response downloadFile(@PathParam("id") String fileId) {

507

// implementation

508

}

509

```

510

511

### Best Practices

512

513

1. **Document all possible responses** - Include success, client error, and server error scenarios

514

2. **Use appropriate HTTP status codes** - Follow HTTP specification and REST conventions

515

3. **Provide meaningful messages** - Clear, human-readable descriptions of each response

516

4. **Include error response models** - Document the structure of error responses

517

5. **Document response headers** - Include important headers like Location, ETag, etc.

518

6. **Use container types** - Specify "List", "Set", or "Map" for collection responses

519

7. **Document async patterns** - Include 202 responses for long-running operations

520

8. **Consider edge cases** - Document rate limiting, validation errors, conflicts, etc.

521

9. **Be consistent** - Use consistent response patterns across your API

522

10. **Include examples** - Provide sample response bodies in your models