or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

content-streaming.mdhttp-clients.mdhttp-messages.mdindex.mdmetrics.mdservice-discovery.mdtls-configuration.md

http-clients.mddocs/

0

# HTTP Client Interfaces

1

2

Core synchronous and asynchronous HTTP client interfaces that all implementations must provide. These interfaces define the contract for making HTTP requests, handling responses, and managing client lifecycle.

3

4

## Capabilities

5

6

### SdkHttpClient

7

8

Main interface for synchronous HTTP client implementations. Implementations must be thread-safe and immutable.

9

10

```java { .api }

11

/**

12

* Interface to take a representation of an HTTP request, make an HTTP call,

13

* and return a representation of an HTTP response.

14

* Implementations MUST be thread safe.

15

*/

16

@Immutable

17

@ThreadSafe

18

@SdkPublicApi

19

public interface SdkHttpClient extends SdkAutoCloseable {

20

/**

21

* Create a ExecutableHttpRequest that can be used to execute the HTTP request.

22

* @param request Representation of an HTTP request

23

* @return Task that can execute an HTTP request and can be aborted

24

*/

25

ExecutableHttpRequest prepareRequest(HttpExecuteRequest request);

26

27

/**

28

* Each HTTP client implementation should return a well-formed client name

29

* that allows requests to be identifiable back to the client that made the request.

30

* @return String containing the name of the client

31

*/

32

default String clientName() {

33

return "UNKNOWN";

34

}

35

36

/**

37

* Close the HTTP client and release any resources

38

*/

39

void close();

40

}

41

```

42

43

**Usage Example:**

44

45

```java

46

public class MyHttpClient implements SdkHttpClient {

47

private final ConnectionPool connectionPool;

48

49

public MyHttpClient(ConnectionPool connectionPool) {

50

this.connectionPool = connectionPool;

51

}

52

53

@Override

54

public ExecutableHttpRequest prepareRequest(HttpExecuteRequest request) {

55

return new MyExecutableHttpRequest(request, connectionPool);

56

}

57

58

@Override

59

public String clientName() {

60

return "MyCustomHttpClientSync";

61

}

62

63

@Override

64

public void close() {

65

connectionPool.shutdown();

66

}

67

}

68

```

69

70

### SdkHttpClient.Builder

71

72

Builder interface for constructing SdkHttpClient instances with service-specific defaults.

73

74

```java { .api }

75

/**

76

* Interface for creating an SdkHttpClient with service specific defaults applied.

77

*/

78

@FunctionalInterface

79

public interface Builder<T extends SdkHttpClient.Builder<T>> extends SdkBuilder<T, SdkHttpClient> {

80

/**

81

* Create a SdkHttpClient with global defaults applied.

82

* This is useful for reusing an HTTP client across multiple services.

83

*/

84

@Override

85

default SdkHttpClient build() {

86

return buildWithDefaults(AttributeMap.empty());

87

}

88

89

/**

90

* Create an SdkHttpClient with service specific defaults and defaults from DefaultsMode applied.

91

* Applying service defaults is optional and some options may not be supported by a particular implementation.

92

* @param serviceDefaults Service specific defaults. Keys will be one of the constants defined in SdkHttpConfigurationOption

93

* @return Created client

94

*/

95

SdkHttpClient buildWithDefaults(AttributeMap serviceDefaults);

96

}

97

```

98

99

### SdkAsyncHttpClient

100

101

Main interface for asynchronous HTTP client implementations. Uses CompletableFuture for async operations and reactive streams for request/response body handling.

102

103

```java { .api }

104

/**

105

* Interface to take a representation of an HTTP request, asynchronously make an HTTP call,

106

* and return a representation of an HTTP response.

107

* Implementations MUST be thread safe.

108

*/

109

@Immutable

110

@ThreadSafe

111

@SdkPublicApi

112

public interface SdkAsyncHttpClient extends SdkAutoCloseable {

113

/**

114

* Execute the request.

115

* @param request The request object

116

* @return The future holding the result of the request execution.

117

* Upon success execution of the request, the future is completed with null,

118

* otherwise it is completed exceptionally.

119

*/

120

CompletableFuture<Void> execute(AsyncExecuteRequest request);

121

122

/**

123

* Each HTTP client implementation should return a well-formed client name

124

* that allows requests to be identifiable back to the client that made the request.

125

* @return String containing the name of the client

126

*/

127

default String clientName() {

128

return "UNKNOWN";

129

}

130

131

/**

132

* Close the HTTP client and release any resources

133

*/

134

void close();

135

}

136

```

137

138

**Usage Example:**

139

140

```java

141

public class MyAsyncHttpClient implements SdkAsyncHttpClient {

142

private final AsyncConnectionPool connectionPool;

143

144

public MyAsyncHttpClient(AsyncConnectionPool connectionPool) {

145

this.connectionPool = connectionPool;

146

}

147

148

@Override

149

public CompletableFuture<Void> execute(AsyncExecuteRequest request) {

150

return connectionPool.acquire()

151

.thenCompose(connection -> {

152

// Execute request using connection

153

return connection.execute(request);

154

})

155

.whenComplete((result, throwable) -> {

156

// Handle response via request.responseHandler()

157

if (throwable != null) {

158

request.responseHandler().onError(throwable);

159

}

160

});

161

}

162

163

@Override

164

public String clientName() {

165

return "MyCustomHttpClientAsync";

166

}

167

168

@Override

169

public void close() {

170

connectionPool.shutdown();

171

}

172

}

173

```

174

175

### SdkAsyncHttpClient.Builder

176

177

Builder interface for constructing SdkAsyncHttpClient instances with service-specific defaults.

178

179

```java { .api }

180

/**

181

* Interface for creating an SdkAsyncHttpClient with service specific defaults applied.

182

*/

183

@FunctionalInterface

184

public interface Builder<T extends SdkAsyncHttpClient.Builder<T>> extends SdkBuilder<T, SdkAsyncHttpClient> {

185

/**

186

* Create a SdkAsyncHttpClient with global defaults applied.

187

* This is useful for reusing an HTTP client across multiple services.

188

*/

189

@Override

190

default SdkAsyncHttpClient build() {

191

return buildWithDefaults(AttributeMap.empty());

192

}

193

194

/**

195

* Create an SdkAsyncHttpClient with service specific defaults applied.

196

* Applying service defaults is optional and some options may not be supported by a particular implementation.

197

* @param serviceDefaults Service specific defaults. Keys will be one of the constants defined in SdkHttpConfigurationOption

198

* @return Created client

199

*/

200

SdkAsyncHttpClient buildWithDefaults(AttributeMap serviceDefaults);

201

}

202

```

203

204

### ExecutableHttpRequest

205

206

Interface for HTTP requests that can be executed and aborted. Used by synchronous HTTP clients.

207

208

```java { .api }

209

/**

210

* HTTP request that can be invoked and cancelled.

211

*/

212

public interface ExecutableHttpRequest extends Callable<HttpExecuteResponse>, Abortable {

213

/**

214

* Execute the HTTP request

215

* @return HTTP response with optional body stream

216

* @throws IOException if request execution fails

217

*/

218

HttpExecuteResponse call() throws IOException;

219

220

/**

221

* Abort the request execution

222

*/

223

void abort();

224

}

225

```

226

227

**Usage Example:**

228

229

```java

230

public class MyExecutableHttpRequest implements ExecutableHttpRequest {

231

private final HttpExecuteRequest request;

232

private final ConnectionPool connectionPool;

233

private volatile boolean aborted = false;

234

235

public MyExecutableHttpRequest(HttpExecuteRequest request, ConnectionPool connectionPool) {

236

this.request = request;

237

this.connectionPool = connectionPool;

238

}

239

240

@Override

241

public HttpExecuteResponse call() throws IOException {

242

if (aborted) {

243

throw new IOException("Request was aborted");

244

}

245

246

// Acquire connection and execute request

247

Connection connection = connectionPool.acquire();

248

try {

249

// Send request and receive response

250

HttpResponse response = connection.execute(request.httpRequest());

251

252

// Create response with optional body stream

253

return HttpExecuteResponse.builder()

254

.response(response)

255

.responseBody(response.getBodyStream())

256

.build();

257

} finally {

258

connectionPool.release(connection);

259

}

260

}

261

262

@Override

263

public void abort() {

264

aborted = true;

265

// Interrupt any ongoing execution

266

}

267

}

268

```

269

270

## Implementation Guidelines

271

272

### Thread Safety Requirements

273

274

All HTTP client implementations must be thread-safe and support concurrent request execution. Clients should use immutable configurations and thread-safe connection pooling.

275

276

### Resource Management

277

278

Implementations should properly manage resources including:

279

- Connection pools and active connections

280

- I/O threads and executors

281

- SSL contexts and certificate stores

282

- Memory buffers and streams

283

284

### Error Handling

285

286

Clients should handle various error conditions gracefully:

287

- Network connectivity issues

288

- SSL/TLS handshake failures

289

- HTTP protocol errors

290

- Request/response timeout scenarios

291

- Resource exhaustion situations

292

293

### Metrics Integration

294

295

Implementations should integrate with the AWS SDK metrics system using the metrics constants defined in `HttpMetric` and `Http2Metric` classes.