or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdauthentication.mdclient-traits.mdcryptography.mdexceptions.mdhttp-client.mdhttp-policies.mdindex.mdmodels.mdserialization.mdutilities.md

annotations.mddocs/

0

# HTTP Annotations

1

2

Declarative annotations for building REST APIs with automatic HTTP request generation, parameter binding, and response handling. These annotations enable method-based service client interfaces that are processed by RestProxy.

3

4

## Capabilities

5

6

### HTTP Method Annotations

7

8

Annotations for specifying HTTP methods and request paths for service interface methods.

9

10

```java { .api }

11

/**

12

* HTTP GET method annotation.

13

*/

14

@Target(ElementType.METHOD)

15

@Retention(RetentionPolicy.RUNTIME)

16

@interface Get {

17

/**

18

* Get the relative path for the annotated method's GET URL.

19

* @return The relative path for the annotated method's GET URL

20

*/

21

String value();

22

}

23

24

/**

25

* HTTP POST method annotation.

26

*/

27

@Target(ElementType.METHOD)

28

@Retention(RetentionPolicy.RUNTIME)

29

@interface Post {

30

/**

31

* Get the relative path for the annotated method's POST URL.

32

* @return The relative path for the annotated method's POST URL

33

*/

34

String value();

35

}

36

37

/**

38

* HTTP PUT method annotation.

39

*/

40

@Target(ElementType.METHOD)

41

@Retention(RetentionPolicy.RUNTIME)

42

@interface Put {

43

/**

44

* Get the relative path for the annotated method's PUT URL.

45

* @return The relative path for the annotated method's PUT URL

46

*/

47

String value();

48

}

49

50

/**

51

* HTTP PATCH method annotation.

52

*/

53

@Target(ElementType.METHOD)

54

@Retention(RetentionPolicy.RUNTIME)

55

@interface Patch {

56

/**

57

* Get the relative path for the annotated method's PATCH URL.

58

* @return The relative path for the annotated method's PATCH URL

59

*/

60

String value();

61

}

62

63

/**

64

* HTTP DELETE method annotation.

65

*/

66

@Target(ElementType.METHOD)

67

@Retention(RetentionPolicy.RUNTIME)

68

@interface Delete {

69

/**

70

* Get the relative path for the annotated method's DELETE URL.

71

* @return The relative path for the annotated method's DELETE URL

72

*/

73

String value();

74

}

75

76

/**

77

* HTTP HEAD method annotation.

78

*/

79

@Target(ElementType.METHOD)

80

@Retention(RetentionPolicy.RUNTIME)

81

@interface Head {

82

/**

83

* Get the relative path for the annotated method's HEAD URL.

84

* @return The relative path for the annotated method's HEAD URL

85

*/

86

String value();

87

}

88

89

/**

90

* HTTP OPTIONS method annotation.

91

*/

92

@Target(ElementType.METHOD)

93

@Retention(RetentionPolicy.RUNTIME)

94

@interface Options {

95

/**

96

* Get the relative path for the annotated method's OPTIONS URL.

97

* @return The relative path for the annotated method's OPTIONS URL

98

*/

99

String value();

100

}

101

```

102

103

### Parameter Binding Annotations

104

105

Annotations for binding method parameters to different parts of HTTP requests.

106

107

```java { .api }

108

/**

109

* Annotation to annotate a parameter to be substituted into a path segment in a REST endpoint URL.

110

*/

111

@Target(ElementType.PARAMETER)

112

@Retention(RetentionPolicy.RUNTIME)

113

@interface PathParam {

114

/**

115

* The name of the variable in the endpoint URI template which will be replaced with the value of the parameter annotated with this annotation.

116

* @return The name of the variable in the endpoint URI template

117

*/

118

String value();

119

120

/**

121

* A value true for this argument indicates that value of {@link #value()} is already encoded hence engine should not encode it.

122

* @return Whether or not this path parameter is already encoded

123

*/

124

boolean encoded() default false;

125

}

126

127

/**

128

* Annotation to annotate a parameter to be substituted into a query parameter in a REST endpoint URL.

129

*/

130

@Target(ElementType.PARAMETER)

131

@Retention(RetentionPolicy.RUNTIME)

132

@interface QueryParam {

133

/**

134

* The name of the variable in the endpoint URI template which will be replaced with the value of the parameter annotated with this annotation.

135

* @return The name of the variable in the endpoint URI template

136

*/

137

String value();

138

139

/**

140

* A value true for this argument indicates that value of {@link #value()} is already encoded hence engine should not encode it.

141

* @return Whether or not this query parameter is already encoded

142

*/

143

boolean encoded() default false;

144

145

/**

146

* A value true for this argument indicates that the REST API expects multiple parameters with the same name and different values.

147

* @return Whether or not the query parameter supports multiple values

148

*/

149

boolean multipleQueryParams() default false;

150

}

151

152

/**

153

* Annotation to annotate a parameter to be substituted into a header in a REST API request.

154

*/

155

@Target(ElementType.PARAMETER)

156

@Retention(RetentionPolicy.RUNTIME)

157

@interface HeaderParam {

158

/**

159

* The name of the header in the REST API request that the parameter should be added to.

160

* @return The name of the header

161

*/

162

String value();

163

}

164

165

/**

166

* Annotation to annotate a parameter to be substituted into a form parameter in a REST API request.

167

*/

168

@Target(ElementType.PARAMETER)

169

@Retention(RetentionPolicy.RUNTIME)

170

@interface FormParam {

171

/**

172

* The name of the form parameter.

173

* @return The name of the form parameter

174

*/

175

String value();

176

}

177

178

/**

179

* Annotation to annotate a parameter to be sent to a REST endpoint as HTTP request content.

180

*/

181

@Target(ElementType.PARAMETER)

182

@Retention(RetentionPolicy.RUNTIME)

183

@interface BodyParam {

184

/**

185

* Content type that the body should be treated as when sending to the REST API.

186

* @return The Content-Type for the body

187

*/

188

String value();

189

}

190

191

/**

192

* Annotation to annotate a parameter to be substituted into the host for a REST API call.

193

*/

194

@Target(ElementType.PARAMETER)

195

@Retention(RetentionPolicy.RUNTIME)

196

@interface HostParam {

197

/**

198

* The name of the variable in the endpoint URI template which will be replaced with the value of the parameter annotated with this annotation.

199

* @return The name of the variable in the endpoint URI template

200

*/

201

String value();

202

}

203

204

/**

205

* Annotation to annotate a parameter that contains all of the headers for a REST API call.

206

*/

207

@Target(ElementType.PARAMETER)

208

@Retention(RetentionPolicy.RUNTIME)

209

@interface HeaderCollection {

210

/**

211

* The prefix that will be prepended to each header name in the collection.

212

* @return The prefix for header names

213

*/

214

String value() default "";

215

}

216

```

217

218

### Response and Error Handling Annotations

219

220

Annotations for specifying expected responses and exception handling behavior.

221

222

```java { .api }

223

/**

224

* Annotation to annotate list of HTTP status codes that are expected in response from a REST API.

225

*/

226

@Target(ElementType.METHOD)

227

@Retention(RetentionPolicy.RUNTIME)

228

@interface ExpectedResponses {

229

/**

230

* The expected success status codes for the annotated method.

231

* @return The expected success status codes

232

*/

233

int[] value();

234

}

235

236

/**

237

* Annotation for the type of exception that should be thrown when the API returns an error status code.

238

*/

239

@Target(ElementType.METHOD)

240

@Retention(RetentionPolicy.RUNTIME)

241

@interface UnexpectedResponseExceptionType {

242

/**

243

* The exception type to throw when the API returns an unexpected status code.

244

* @return The exception type

245

*/

246

Class<? extends HttpResponseException> value();

247

248

/**

249

* HTTP status codes that should trigger this exception type.

250

* @return Array of status codes

251

*/

252

int[] code() default {};

253

}

254

255

/**

256

* Container annotation for multiple UnexpectedResponseExceptionType annotations.

257

*/

258

@Target(ElementType.METHOD)

259

@Retention(RetentionPolicy.RUNTIME)

260

@interface UnexpectedResponseExceptionTypes {

261

/**

262

* Array of UnexpectedResponseExceptionType annotations.

263

* @return Array of exception type annotations

264

*/

265

UnexpectedResponseExceptionType[] value();

266

}

267

268

/**

269

* Annotation to indicate that the method represents a resumable operation.

270

*/

271

@Target(ElementType.METHOD)

272

@Retention(RetentionPolicy.RUNTIME)

273

@interface ResumeOperation {

274

/**

275

* The name of the operation for resumption.

276

* @return Operation name

277

*/

278

String value() default "";

279

}

280

```

281

282

### Service Definition Annotations

283

284

Annotations for defining service interfaces and client characteristics.

285

286

```java { .api }

287

/**

288

* Annotation for interfaces that represent REST API service interfaces.

289

*/

290

@Target(ElementType.TYPE)

291

@Retention(RetentionPolicy.RUNTIME)

292

@interface ServiceInterface {

293

/**

294

* The name of the service. This is used in telemetry and logging.

295

* @return The name of the service

296

*/

297

String name();

298

}

299

300

/**

301

* Annotation for service client classes.

302

*/

303

@Target(ElementType.TYPE)

304

@Retention(RetentionPolicy.RUNTIME)

305

@interface ServiceClient {

306

/**

307

* The builder class that is used to build instances of the service client.

308

* @return The builder class

309

*/

310

Class<?> builder();

311

312

/**

313

* Indicates whether the service client is asynchronous.

314

* @return true if the service client is asynchronous

315

*/

316

boolean isAsync() default false;

317

318

/**

319

* The service interfaces that this client implements.

320

* @return Array of service interface classes

321

*/

322

Class<?>[] serviceInterfaces() default {};

323

}

324

325

/**

326

* Annotation for service client builder classes.

327

*/

328

@Target(ElementType.TYPE)

329

@Retention(RetentionPolicy.RUNTIME)

330

@interface ServiceClientBuilder {

331

/**

332

* An array of classes that this builder can build.

333

* @return Array of service client classes this builder can create

334

*/

335

Class<?>[] serviceClients();

336

337

/**

338

* The protocol that the built service clients will use to communicate.

339

* @return The service client protocol

340

*/

341

ServiceClientProtocol protocol() default ServiceClientProtocol.HTTP;

342

}

343

344

/**

345

* Annotation for service client methods that perform network operations.

346

*/

347

@Target(ElementType.METHOD)

348

@Retention(RetentionPolicy.RUNTIME)

349

@interface ServiceMethod {

350

/**

351

* The expected return type from the service method.

352

* @return The return type

353

*/

354

ReturnType returns();

355

}

356

```

357

358

### Header and Host Configuration Annotations

359

360

Annotations for configuring headers and host information.

361

362

```java { .api }

363

/**

364

* Annotation for static headers that will be sent to a REST endpoint.

365

*/

366

@Target(ElementType.METHOD)

367

@Retention(RetentionPolicy.RUNTIME)

368

@interface Headers {

369

/**

370

* List of static headers in "name: value" format.

371

* @return Array of header strings

372

*/

373

String[] value();

374

}

375

376

/**

377

* Annotation for specifying the host for REST API calls.

378

*/

379

@Target(ElementType.TYPE)

380

@Retention(RetentionPolicy.RUNTIME)

381

@interface Host {

382

/**

383

* The host URL for the REST service. Can contain parameters enclosed in braces.

384

* @return The host URL

385

*/

386

String value();

387

}

388

```

389

390

### Marker Annotations

391

392

Annotations for marking classes with specific characteristics.

393

394

```java { .api }

395

/**

396

* Annotation for classes that provide a fluent API.

397

*/

398

@Target(ElementType.TYPE)

399

@Retention(RetentionPolicy.RUNTIME)

400

@interface Fluent {

401

// Marker annotation - no methods

402

}

403

404

/**

405

* Annotation for classes that are immutable.

406

*/

407

@Target(ElementType.TYPE)

408

@Retention(RetentionPolicy.RUNTIME)

409

@interface Immutable {

410

// Marker annotation - no methods

411

}

412

413

/**

414

* Annotation for generated classes.

415

*/

416

@Target(ElementType.TYPE)

417

@Retention(RetentionPolicy.RUNTIME)

418

@interface Generated {

419

/**

420

* The name of the code generator.

421

* @return Generator name

422

*/

423

String value() default "";

424

425

/**

426

* Date and time the code was generated.

427

* @return Generation timestamp

428

*/

429

String date() default "";

430

431

/**

432

* Comments about the generation.

433

* @return Generation comments

434

*/

435

String comments() default "";

436

}

437

438

/**

439

* Annotation for JSON flattening in serialization.

440

*/

441

@Target(ElementType.TYPE)

442

@Retention(RetentionPolicy.RUNTIME)

443

@interface JsonFlatten {

444

// Marker annotation for JSON processing

445

}

446

```

447

448

### Supporting Enumerations

449

450

Enumerations used by the annotation system.

451

452

```java { .api }

453

/**

454

* Enumeration of return types for ServiceMethod annotation.

455

*/

456

enum ReturnType {

457

/**

458

* Return type is a single entity.

459

*/

460

SINGLE,

461

462

/**

463

* Return type is a collection or list of entities.

464

*/

465

COLLECTION,

466

467

/**

468

* Return type represents a long-running operation.

469

*/

470

LONG_RUNNING_OPERATION

471

}

472

473

/**

474

* Enumeration of service client protocols.

475

*/

476

enum ServiceClientProtocol {

477

/**

478

* HTTP protocol for REST services.

479

*/

480

HTTP,

481

482

/**

483

* AMQP protocol for message-based services.

484

*/

485

AMQP

486

}

487

```

488

489

## Usage Examples

490

491

### Defining REST Service Interface

492

493

```java

494

import com.azure.core.annotation.*;

495

import com.azure.core.http.rest.Response;

496

import com.azure.core.util.Context;

497

import reactor.core.publisher.Mono;

498

499

@ServiceInterface(name = "UserService")

500

@Host("https://api.example.com")

501

interface UserServiceClient {

502

503

@Get("/users/{userId}")

504

@ExpectedResponses({200})

505

@UnexpectedResponseExceptionType(ResourceNotFoundException.class)

506

Mono<Response<User>> getUser(

507

@PathParam("userId") String userId,

508

@HeaderParam("Accept") String acceptHeader,

509

Context context);

510

511

@Get("/users")

512

@ExpectedResponses({200})

513

@Headers({"Accept: application/json", "User-Agent: MyApp/1.0"})

514

Mono<Response<List<User>>> listUsers(

515

@QueryParam("limit") Integer limit,

516

@QueryParam("offset") Integer offset,

517

@QueryParam("filter") String filter,

518

Context context);

519

520

@Post("/users")

521

@ExpectedResponses({201})

522

@UnexpectedResponseExceptionTypes({

523

@UnexpectedResponseExceptionType(value = ClientAuthenticationException.class, code = {401, 403}),

524

@UnexpectedResponseExceptionType(value = ResourceExistsException.class, code = {409})

525

})

526

Mono<Response<User>> createUser(

527

@BodyParam("application/json") User user,

528

@HeaderParam("Content-Type") String contentType,

529

Context context);

530

531

@Put("/users/{userId}")

532

@ExpectedResponses({200, 204})

533

Mono<Response<User>> updateUser(

534

@PathParam("userId") String userId,

535

@BodyParam("application/json") User user,

536

Context context);

537

538

@Delete("/users/{userId}")

539

@ExpectedResponses({204})

540

Mono<Response<Void>> deleteUser(

541

@PathParam("userId") String userId,

542

Context context);

543

}

544

```

545

546

### Service Client Implementation

547

548

```java

549

import com.azure.core.annotation.*;

550

551

@ServiceClient(builder = UserServiceClientBuilder.class, isAsync = false)

552

class UserServiceClientImpl {

553

private final UserServiceClient client;

554

555

UserServiceClientImpl(HttpPipeline pipeline) {

556

this.client = RestProxy.create(UserServiceClient.class, pipeline);

557

}

558

559

@ServiceMethod(returns = ReturnType.SINGLE)

560

public User getUser(String userId) {

561

return client.getUser(userId, "application/json", Context.NONE)

562

.block()

563

.getValue();

564

}

565

566

@ServiceMethod(returns = ReturnType.COLLECTION)

567

public List<User> listUsers(Integer limit, Integer offset, String filter) {

568

return client.listUsers(limit, offset, filter, Context.NONE)

569

.block()

570

.getValue();

571

}

572

573

@ServiceMethod(returns = ReturnType.SINGLE)

574

public User createUser(User user) {

575

return client.createUser(user, "application/json", Context.NONE)

576

.block()

577

.getValue();

578

}

579

}

580

```

581

582

### Service Client Builder

583

584

```java

585

import com.azure.core.annotation.ServiceClientBuilder;

586

import com.azure.core.client.traits.*;

587

588

@ServiceClientBuilder(serviceClients = {UserServiceClientImpl.class, UserServiceAsyncClient.class})

589

@Fluent

590

class UserServiceClientBuilder implements

591

HttpTrait<UserServiceClientBuilder>,

592

TokenCredentialTrait<UserServiceClientBuilder>,

593

EndpointTrait<UserServiceClientBuilder> {

594

595

private HttpClient httpClient;

596

private HttpPipeline pipeline;

597

private TokenCredential credential;

598

private String endpoint;

599

private List<HttpPipelinePolicy> policies = new ArrayList<>();

600

601

@Override

602

public UserServiceClientBuilder httpClient(HttpClient httpClient) {

603

this.httpClient = httpClient;

604

return this;

605

}

606

607

@Override

608

public UserServiceClientBuilder pipeline(HttpPipeline pipeline) {

609

this.pipeline = pipeline;

610

return this;

611

}

612

613

@Override

614

public UserServiceClientBuilder addPolicy(HttpPipelinePolicy policy) {

615

this.policies.add(policy);

616

return this;

617

}

618

619

@Override

620

public UserServiceClientBuilder credential(TokenCredential credential) {

621

this.credential = credential;

622

return this;

623

}

624

625

@Override

626

public UserServiceClientBuilder endpoint(String endpoint) {

627

this.endpoint = endpoint;

628

return this;

629

}

630

631

public UserServiceClientImpl buildClient() {

632

HttpPipeline pipeline = buildPipeline();

633

return new UserServiceClientImpl(pipeline);

634

}

635

636

public UserServiceAsyncClient buildAsyncClient() {

637

HttpPipeline pipeline = buildPipeline();

638

return new UserServiceAsyncClient(pipeline);

639

}

640

641

private HttpPipeline buildPipeline() {

642

if (pipeline != null) {

643

return pipeline;

644

}

645

646

List<HttpPipelinePolicy> allPolicies = new ArrayList<>();

647

allPolicies.add(new UserAgentPolicy("UserService/1.0"));

648

649

if (credential != null) {

650

allPolicies.add(new BearerTokenAuthenticationPolicy(credential,

651

"https://api.example.com/.default"));

652

}

653

654

allPolicies.addAll(policies);

655

allPolicies.add(new RetryPolicy());

656

657

return new HttpPipelineBuilder()

658

.httpClient(httpClient != null ? httpClient : HttpClient.createDefault())

659

.policies(allPolicies.toArray(new HttpPipelinePolicy[0]))

660

.build();

661

}

662

}

663

```

664

665

### Complex Parameter Binding

666

667

```java

668

@ServiceInterface(name = "SearchService")

669

interface SearchServiceClient {

670

671

@Get("/search")

672

@ExpectedResponses({200})

673

Mono<Response<SearchResults>> search(

674

@QueryParam("q") String query,

675

@QueryParam("filters", multipleQueryParams = true) List<String> filters,

676

@QueryParam("sort") String sortBy,

677

@QueryParam("limit") Integer limit,

678

@QueryParam("offset") Integer offset,

679

@HeaderCollection("X-Custom-") Map<String, String> customHeaders,

680

Context context);

681

682

@Post("/documents/batch")

683

@ExpectedResponses({200})

684

@Headers({"Content-Type: application/json"})

685

Mono<Response<BatchResult>> batchOperation(

686

@BodyParam("application/json") BatchRequest request,

687

@HeaderParam("X-Request-ID") String requestId,

688

@QueryParam("timeout") Duration timeout,

689

Context context);

690

}

691

692

// Usage

693

Map<String, String> customHeaders = Map.of(

694

"Trace-ID", "trace-123",

695

"Client-Version", "1.0"

696

);

697

698

List<String> filters = List.of(

699

"category:electronics",

700

"price:100-500",

701

"availability:in-stock"

702

);

703

704

searchClient.search("laptop", filters, "price", 20, 0, customHeaders, Context.NONE);

705

```

706

707

### Host Parameter Substitution

708

709

```java

710

@ServiceInterface(name = "MultiRegionService")

711

@Host("https://{accountName}.{region}.example.com")

712

interface MultiRegionServiceClient {

713

714

@Get("/status")

715

@ExpectedResponses({200})

716

Mono<Response<ServiceStatus>> getStatus(

717

@HostParam("accountName") String accountName,

718

@HostParam("region") String region,

719

Context context);

720

721

@Get("/data/{dataId}")

722

@ExpectedResponses({200})

723

Mono<Response<Data>> getData(

724

@HostParam("accountName") String accountName,

725

@HostParam("region") String region,

726

@PathParam("dataId") String dataId,

727

Context context);

728

}

729

730

// Usage - different regions and accounts

731

client.getStatus("myaccount", "us-west-2", Context.NONE);

732

client.getData("myaccount", "eu-west-1", "data123", Context.NONE);

733

```

734

735

### Form Data and File Uploads

736

737

```java

738

@ServiceInterface(name = "FileService")

739

interface FileServiceClient {

740

741

@Post("/upload")

742

@ExpectedResponses({200, 201})

743

Mono<Response<FileMetadata>> uploadFile(

744

@FormParam("filename") String filename,

745

@FormParam("description") String description,

746

@FormParam("tags") List<String> tags,

747

@BodyParam("application/octet-stream") BinaryData fileData,

748

Context context);

749

750

@Post("/forms/submit")

751

@ExpectedResponses({200})

752

@Headers({"Content-Type: application/x-www-form-urlencoded"})

753

Mono<Response<FormResult>> submitForm(

754

@FormParam("name") String name,

755

@FormParam("email") String email,

756

@FormParam("message") String message,

757

Context context);

758

}

759

```

760

761

### Long Running Operations

762

763

```java

764

@ServiceInterface(name = "ProcessingService")

765

interface ProcessingServiceClient {

766

767

@Post("/process")

768

@ExpectedResponses({202})

769

@ServiceMethod(returns = ReturnType.LONG_RUNNING_OPERATION)

770

Mono<Response<ProcessingOperation>> startProcessing(

771

@BodyParam("application/json") ProcessingRequest request,

772

Context context);

773

774

@Get("/operations/{operationId}")

775

@ExpectedResponses({200})

776

@ResumeOperation

777

Mono<Response<ProcessingOperation>> getOperation(

778

@PathParam("operationId") String operationId,

779

Context context);

780

781

@Delete("/operations/{operationId}")

782

@ExpectedResponses({204})

783

Mono<Response<Void>> cancelOperation(

784

@PathParam("operationId") String operationId,

785

Context context);

786

}

787

```

788

789

### Generated Model Classes

790

791

```java

792

@Generated("AutoRest")

793

@Fluent

794

@JsonFlatten

795

class User {

796

private String id;

797

private String name;

798

private String email;

799

private Map<String, Object> additionalProperties;

800

801

// Getters and setters...

802

}

803

804

@Generated("AutoRest")

805

@Immutable

806

class UserList {

807

private final List<User> users;

808

private final String continuationToken;

809

810

UserList(List<User> users, String continuationToken) {

811

this.users = users;

812

this.continuationToken = continuationToken;

813

}

814

815

// Getters only (immutable)...

816

}

817

```