CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-software-amazon-awssdk--http-client-spi

Service Provider Interface (SPI) for HTTP client implementations in the AWS SDK for Java v2

Overview
Eval results
Files

http-clients.mddocs/

HTTP Client Interfaces

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.

Capabilities

SdkHttpClient

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

/**
 * Interface to take a representation of an HTTP request, make an HTTP call, 
 * and return a representation of an HTTP response.
 * Implementations MUST be thread safe.
 */
@Immutable
@ThreadSafe
@SdkPublicApi
public interface SdkHttpClient extends SdkAutoCloseable {
    /**
     * Create a ExecutableHttpRequest that can be used to execute the HTTP request.
     * @param request Representation of an HTTP request
     * @return Task that can execute an HTTP request and can be aborted
     */
    ExecutableHttpRequest prepareRequest(HttpExecuteRequest request);
    
    /**
     * Each HTTP client implementation should return a well-formed client name
     * that allows requests to be identifiable back to the client that made the request.
     * @return String containing the name of the client
     */
    default String clientName() {
        return "UNKNOWN";
    }
    
    /**
     * Close the HTTP client and release any resources
     */
    void close();
}

Usage Example:

public class MyHttpClient implements SdkHttpClient {
    private final ConnectionPool connectionPool;
    
    public MyHttpClient(ConnectionPool connectionPool) {
        this.connectionPool = connectionPool;
    }
    
    @Override
    public ExecutableHttpRequest prepareRequest(HttpExecuteRequest request) {
        return new MyExecutableHttpRequest(request, connectionPool);
    }
    
    @Override
    public String clientName() {
        return "MyCustomHttpClientSync";
    }
    
    @Override
    public void close() {
        connectionPool.shutdown();
    }
}

SdkHttpClient.Builder

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

/**
 * Interface for creating an SdkHttpClient with service specific defaults applied.
 */
@FunctionalInterface
public interface Builder<T extends SdkHttpClient.Builder<T>> extends SdkBuilder<T, SdkHttpClient> {
    /**
     * Create a SdkHttpClient with global defaults applied. 
     * This is useful for reusing an HTTP client across multiple services.
     */
    @Override
    default SdkHttpClient build() {
        return buildWithDefaults(AttributeMap.empty());
    }
    
    /**
     * Create an SdkHttpClient with service specific defaults and defaults from DefaultsMode applied.
     * Applying service defaults is optional and some options may not be supported by a particular implementation.
     * @param serviceDefaults Service specific defaults. Keys will be one of the constants defined in SdkHttpConfigurationOption
     * @return Created client
     */
    SdkHttpClient buildWithDefaults(AttributeMap serviceDefaults);
}

SdkAsyncHttpClient

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

/**
 * Interface to take a representation of an HTTP request, asynchronously make an HTTP call, 
 * and return a representation of an HTTP response.
 * Implementations MUST be thread safe.
 */
@Immutable
@ThreadSafe
@SdkPublicApi
public interface SdkAsyncHttpClient extends SdkAutoCloseable {
    /**
     * Execute the request.
     * @param request The request object
     * @return The future holding the result of the request execution. 
     *         Upon success execution of the request, the future is completed with null, 
     *         otherwise it is completed exceptionally.
     */
    CompletableFuture<Void> execute(AsyncExecuteRequest request);
    
    /**
     * Each HTTP client implementation should return a well-formed client name
     * that allows requests to be identifiable back to the client that made the request.
     * @return String containing the name of the client
     */
    default String clientName() {
        return "UNKNOWN";
    }
    
    /**
     * Close the HTTP client and release any resources
     */
    void close();
}

Usage Example:

public class MyAsyncHttpClient implements SdkAsyncHttpClient {
    private final AsyncConnectionPool connectionPool;
    
    public MyAsyncHttpClient(AsyncConnectionPool connectionPool) {
        this.connectionPool = connectionPool;
    }
    
    @Override
    public CompletableFuture<Void> execute(AsyncExecuteRequest request) {
        return connectionPool.acquire()
            .thenCompose(connection -> {
                // Execute request using connection
                return connection.execute(request);
            })
            .whenComplete((result, throwable) -> {
                // Handle response via request.responseHandler()
                if (throwable != null) {
                    request.responseHandler().onError(throwable);
                }
            });
    }
    
    @Override
    public String clientName() {
        return "MyCustomHttpClientAsync";
    }
    
    @Override
    public void close() {
        connectionPool.shutdown();
    }
}

SdkAsyncHttpClient.Builder

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

/**
 * Interface for creating an SdkAsyncHttpClient with service specific defaults applied.
 */
@FunctionalInterface
public interface Builder<T extends SdkAsyncHttpClient.Builder<T>> extends SdkBuilder<T, SdkAsyncHttpClient> {
    /**
     * Create a SdkAsyncHttpClient with global defaults applied.
     * This is useful for reusing an HTTP client across multiple services.
     */
    @Override
    default SdkAsyncHttpClient build() {
        return buildWithDefaults(AttributeMap.empty());
    }
    
    /**
     * Create an SdkAsyncHttpClient with service specific defaults applied.
     * Applying service defaults is optional and some options may not be supported by a particular implementation.
     * @param serviceDefaults Service specific defaults. Keys will be one of the constants defined in SdkHttpConfigurationOption
     * @return Created client
     */
    SdkAsyncHttpClient buildWithDefaults(AttributeMap serviceDefaults);
}

ExecutableHttpRequest

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

/**
 * HTTP request that can be invoked and cancelled.
 */
public interface ExecutableHttpRequest extends Callable<HttpExecuteResponse>, Abortable {
    /**
     * Execute the HTTP request
     * @return HTTP response with optional body stream
     * @throws IOException if request execution fails
     */
    HttpExecuteResponse call() throws IOException;
    
    /**
     * Abort the request execution
     */
    void abort();
}

Usage Example:

public class MyExecutableHttpRequest implements ExecutableHttpRequest {
    private final HttpExecuteRequest request;
    private final ConnectionPool connectionPool;
    private volatile boolean aborted = false;
    
    public MyExecutableHttpRequest(HttpExecuteRequest request, ConnectionPool connectionPool) {
        this.request = request;
        this.connectionPool = connectionPool;
    }
    
    @Override
    public HttpExecuteResponse call() throws IOException {
        if (aborted) {
            throw new IOException("Request was aborted");
        }
        
        // Acquire connection and execute request
        Connection connection = connectionPool.acquire();
        try {
            // Send request and receive response
            HttpResponse response = connection.execute(request.httpRequest());
            
            // Create response with optional body stream
            return HttpExecuteResponse.builder()
                .response(response)
                .responseBody(response.getBodyStream())
                .build();
        } finally {
            connectionPool.release(connection);
        }
    }
    
    @Override
    public void abort() {
        aborted = true;
        // Interrupt any ongoing execution
    }
}

Implementation Guidelines

Thread Safety Requirements

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

Resource Management

Implementations should properly manage resources including:

  • Connection pools and active connections
  • I/O threads and executors
  • SSL contexts and certificate stores
  • Memory buffers and streams

Error Handling

Clients should handle various error conditions gracefully:

  • Network connectivity issues
  • SSL/TLS handshake failures
  • HTTP protocol errors
  • Request/response timeout scenarios
  • Resource exhaustion situations

Metrics Integration

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

Install with Tessl CLI

npx tessl i tessl/maven-software-amazon-awssdk--http-client-spi

docs

content-streaming.md

http-clients.md

http-messages.md

index.md

metrics.md

service-discovery.md

tls-configuration.md

tile.json