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.