Swiftpack.co - Package - amzn/smoke-http

Build - Master Branch Swift 5.0 Tested Swift 5.1 Tested Swift 5.2 Tested Ubuntu 16.04 Tested Ubuntu 18.04 Tested Join the Smoke Server Side community on gitter Apache 2

SmokeHTTP

SmokeHTTP is a specialization of the generic HTTP client provided by async-http-client, providing the common functionality required to abstract service operations from the underlying HTTP protocol. This library is primarily used by SmokeFramework and SmokeAWS.

This library provides a numer of features on top of those provided by async-http-client-

  1. The HTTPRequestInputProtocol and HTTPResponseOutputProtocol protocols provide a mechanism to deconstruct an input type into the different components of a HTTP request and construct an output type from the components of a HTTP response respectively.
  2. Protocol-based strategies for determining the threading-model for asychronous completion handling.
  3. Support for expontential backoff retries.
  4. Logging and emittion of invocation metrics.
  5. An extension point for handing request-level tracing.

SmokeHTTPClient

To use SmokeHTTPClient, a user can instantiate an HTTPOperationsClient in the constructor of their specific client with instantiated delegates (HTTPClientDelegate, HTTPClientInvocationDelegate) that are used to define client-specific logic.

Support Policy

SmokeHTTP follows the same support policy as followed by SmokeAWS here.

Getting Started

Step 1: Add the SmokeHTTP dependency

SmokeHTTP uses the Swift Package Manager. To use the framework, add the following dependency to your Package.swift-

For swift-tools version 5.2 and greater-

dependencies: [
    .package(url: "https://github.com/amzn/smoke-http.git", from: "2.0.0")
]

.target(name: ..., dependencies: [
    ..., 
    .product(name: "SmokeHTTPClient", package: "smoke-http"),
]),

For swift-tools version 5.1 and prior-

dependencies: [
    .package(url: "https://github.com/amzn/smoke-http.git", from: "2.0.0")
]

.target(
    name: ...,
    dependencies: [..., "SmokeHTTPClient"]),

Step 2: Construct a HTTPOperationsClient

Construct a HTTPClient using the following code-

import SmokeHTTPClient

let httpOperationsClient = HTTPOperationsClient(endpointHostName: endpointHostName,
                                                endpointPort: endpointPort,
                                                contentType: contentType,
                                                clientDelegate: clientDelegate,
                                                connectionTimeoutSeconds: connectionTimeoutSeconds,
                                                eventLoopProvider: = .createNew)

The inputs to this constructor are-

  1. endpointHostName: The hostname to contact for invocations made by this client. Doesn't include the scheme or port.
  • For example dynamodb.us-west-2.amazonaws.com.
  1. endpointPort: The port to contact for invocations made by this client.
  • For example 443
  1. contentType: The content type of the request body for invocations made by this client.
  • For example application/json.
  1. clientDelegate: An instance of a type conforming to the HTTPClientDelegate protocol.
  2. connectionTimeoutSeconds: The timeout in seconds for requests made by this client.
  3. eventLoopProvider: The provider of the event loop for this client. Defaults to creating a new event loop.

Step 3: Execute an invocation of the HTTPOperationsClient

There are a number of variants of the execute call on the HTTPOperationsClient. Below describes one variant but all are broadly similar-

try httpOperationsClient.executeAsyncRetriableWithOutput(
            endpointOverride: nil,
            endpointPath = endpointPath,
            httpMethod: .GET,
            input: InputType,
            completion: completion,
            asyncResponseInvocationStrategy: asyncResponseInvocationStrategy,
            invocationContext: invocationContext,
            retryConfiguration: retryConfiguration,
            retryOnError: retryOnError)

The inputs to this function are-

  1. endpointOverride: Overrides the hostname used for this invocation. Default to nil to use the endpoint provided during the initialization of the client.
  2. endpointPath: The path to contact for this invocation.
  3. httpMethod: The HTTPMethod for this invocation.
  4. input: An instance of a type conforming to the HTTPRequestInputProtocol protocol.
  5. completion: A closure of type (Result<OutputType, HTTPClientError>) -> () used to handle the outcome of the invocation. OutputType must be a type that conforms to the HTTPResponseOutputProtocol protocol.
  6. asyncResponseInvocationStrategy: An invocation strategy for executing the completion handler.
  1. invocationContext: An instance of type HTTPClientInvocationContext.
  2. retryConfiguration: An instance of type HTTPClientRetryConfiguration to indicate how the client should handle automatic retries on failure.
  3. . retryOnError: A closure of type (HTTPClientError) -> Bool that can be used to determine if an automatic retry should occur when the request failures with the provided error.

The complete list of variants for the HTTPOperationsClient.execute* functions are

  1. executeAsyncRetriableWithOutput: Executes a HTTP request asynchronously with built-in support for automatic retries that produces an output.
  2. executeAsyncRetriableWithoutOutput: Executes a HTTP request synchronously with built-in support for automatic retries that doesn't produce an output.
  3. executeAsyncWithoutOutput: Executes a HTTP request asynchronously without built-in support for automatic retries that doesn't produce an output.
  4. executeAsyncWithOutput: Executes a HTTP request asynchronously without built-in support for automatic retries that produces an output.
  5. executeSyncRetriableWithoutOutput: Executes a HTTP request synchronously with built-in support for automatic retries that doesn't produce an output.
  6. executeSyncRetriableWithOutput: Executes a HTTP request synchronously with built-in support for automatic retries that produces an output.
  7. executeSyncWithoutOutput: Executes a HTTP request synchronously without built-in support for automatic retries that doesn't produce an output.
  8. executeSyncWithOutput: Executes a HTTP request synchronously without built-in support for automatic retries that produces an output.

Important Protocols and Types

HTTPClientDelegate

The HTTPClientDelegate protocol provides a number extension points that can be used to customise a client-

Protocol function requirements-

  1. getResponseError: determines the client-specific error based on the HTTP response from the client.
  2. encodeInputAndQueryString: determines the components to be used for the HTTP request based on the input to an invocation
  3. decodeOutput creates an instance of an output type based on the HTTP response from the client.
  4. getTLSConfiguration: retrieves the TLS configuration to be used by the client.

HTTPClientInvocationDelegate

The HTTPClientDelegate protocol provides a number extension points that can be used to customise the invocation of a client-

Protocol property requirements-

  1. specifyContentHeadersForZeroLengthBody: If the Content-Length and Content-Type headers should be sent in the request even when there is no request body.

Protocol function requirements-

  1. addClientSpecificHeaders: determines any additional headers to be added to HTTP request.
  2. handleErrorResponses: determines the client-specific error based on the HTTP response from the client. Overrides HTTPClientDelegate.getResponseError if a non-nil error is returned.

HTTPRequestInputProtocol

The HTTPRequestInputProtocol provides a mechanism used to transform an input into the different parts of a HTTP request. For an example of how this protocol is used to deconstruct an input type into a HTTP request see JSONAWSHttpClientDelegate.encodeInputAndQueryString().

Protocol property requirements-

  1. queryEncodable: Optionally, provides an instance of a type conforming to Encodable that will be used to produce the query for the HTTP request.
  2. pathEncodable: Optionally, provides an instance of a type conforming to Encodable that will be used to provide any tokenized values for the path of the HTTP request.
  3. bodyEncodable: Optionally, provides an instance of a type conforming to Encodable that will be used to produce the body for the HTTP request.
  4. additionalHeadersEncodable: Optionally, provides an instance of a type conforming to Encodable that will be used to produce additional headers for the HTTP request.
  5. pathPostfix: Optionally, provides a string that will be post-pended to the path template prior to having any tokens replaced by values from pathEncodable.

HTTPResponseOutputProtocol

The HTTPResponseOutputProtocol provides a mechanism to construct an output type from the components of a HTTP response. For an example of how this is achieved see JSONAWSHttpClientDelegate.decodeOutput().

Protocol function requirements-

  1. compose: A function that accepts bodyDecodableProvider and headersDecodableProvider closures that can be used to construct parts of the expected output type from parts of the HTTP response.

HTTPClientInvocationContext

The HTTPClientInvocationContext type can be used to customise the invocation of a client.

The inputs to the HTTPClientInvocationContext constructor are-

  1. reporting: An instance of a type conforming to the HTTPClientInvocationReporting protocol.
  2. handlerDelegate: An instance of a type conforming to the HTTPClientInvocationDelegate protocol.

HTTPClientInvocationReporting

The HTTPClientInvocationReporting protocol provides a number of extension points focused on the reporting of a client invocation-

Protocol property requirements-

  1. logger: The logger to use for statements related to the HTTP client invocation
  2. internalRequestId: the internal identity of the request that is making the invocation to the client.
  3. traceContext: An instance of a type conforming to the InvocationTraceContext protocol.
  4. successCounter: Optionally, a Metrics.Counter that will record successful invocations of the client.
  5. failure5XXCounter: Optionally, a Metrics.Counter that will record unsuccessful invocations of the client that return with a 5xx response code.
  6. failure4XXCounter: Optionally, a Metrics.Counter that will record unsuccessful invocations of the client that return with a 4xx response code.
  7. retryCountRecorder: Optionally, a Metrics.Recorder that will record the retry count for invocations of the client.
  8. latencyTimer: Optionally, a Metrics.Recorder that will record the latency of invocations from the client.

InvocationTraceContext

The InvocationTraceContext provides an extension point for request-level tracing.

Protocol function requirements-

  1. handleOutwardsRequestStart: Provides the ability to handle an invocation of the client just prior to the request being sent, including the ability to modify the headers sent in the request.
  2. handleOutwardsRequestSuccess: Provides the ability to handle a successful invocation just after the response has been recieved.
  3. handleOutwardsRequestFailure: Provides the ability to handle a unsuccessful invocation just after the response has been recieved.

License

This library is licensed under the Apache 2.0 License.

Github

link
Stars: 45

Used By

Total: 0

Releases

Add ListEncodingStrategy and ListDecodingStrategy - 2020-05-14 22:10:12

This release of SmokeHTTP provides compatibility with Swift 5.0, Swift 5.1 and Swift 5.2 using SwiftNIO 2.x.

  1. Add ListEncodingStrategy and ListDecodingStrategy. (#60)
  2. Expose the EventLoopGroup of the wrapped HttpClient. (#60)

Official Release of SmokeHTTP 2 - 2020-05-05 20:12:16

This release of SmokeHTTP provides compatibility with Swift 5.0, Swift 5.1 and Swift 5.2 using SwiftNIO 2.x.

  1. Migrate to swift-nio 2.x.
  2. Adopt swift-log for logging
  3. Adopt swift-metrics for metrics.
  4. Adopt async-http-client for core http client functionality.
  5. Provide extension points for basic tracing.

RC 1 release for SmokeHTTP 2 - 2020-04-28 22:42:38

This release of SmokeHTTP provides compatibility with Swift 5.0, Swift 5.1 and Swift 5.2 using SwiftNIO 2.x.

  1. Expose default TLS configuration with non-overridden function. (#58)

General release notes from SmokeHTTP 2.x-

  1. Migrate to swift-nio 2.x.
  2. Adopt swift-log for logging
  3. Adopt swift-metrics for metrics.
  4. Adopt async-http-client for core http client functionality.
  5. Provide extension points for basic tracing.

Beta 1 release for SmokeHTTP 2 - 2020-04-12 16:43:50

This release of SmokeHTTP provides compatibility with Swift 5.0, Swift 5.1 and Swift 5.2 using SwiftNIO 2.x.

There are no changes from 2.0.0-alpha.9.

General release notes from SmokeHTTP 2.x-

  1. Migrate to swift-nio 2.x.
  2. Adopt swift-log for logging
  3. Adopt swift-metrics for metrics.
  4. Adopt async-http-client for core http client functionality.
  5. Provide extension points for basic tracing.

Alpha 9 release for SmokeHTTP 2 - 2020-04-08 16:00:44

This release of SmokeHTTP provides compatibility with Swift 5.0, Swift 5.1 and Swift 5.2 using SwiftNIO 2.x.

  1. Update tools version to 5.2.
  2. Add legacy manifest files for Swift 5.0 and 5.1.
  3. Align package name with repository name.

Alpha 8 release for SmokeHTTP 2 - 2020-04-03 00:22:27

This release of SmokeHTTP provides compatibility with Swift 5.0, Swift 5.1 and Swift 5.2 using SwiftNIO 2.x.

  1. Add more generic StandardHTTPClientCoreInvocationReporting concrete type.

Alpha 7 release for SmokeHTTP 2 - 2020-03-13 21:36:19

This release of SmokeHTTP provides compatibility with Swift 5.0 and Swift 5.1 using SwiftNIO 2.x.

  1. Use https://github.com/swift-server/async-http-client (#42)

Alpha 6 release for SmokeHTTP 2 - 2020-03-11 18:47:12

This release of SmokeHTTP provides compatibility with Swift 5.0 and Swift 5.1 using SwiftNIO 2.x.

  1. Provide an outgoingRequestId as Logger metadata to track the same invocation to a client (#53)

Alpha 5 release for SmokeHTTP 2 - 2020-03-10 20:04:12

This release of SmokeHTTP provides compatibility with Swift 5.0 and Swift 5.1 using SwiftNIO 2.x.

  1. Relax version requirements for swift-metrics. (#49)
  2. Add HTTPClientCoreInvocationReporting protocol and the MockCoreInvocationReporting (#52)

Alpha 4 release for SmokeHTTP 2 - 2020-03-04 03:39:41

  1. Visibility fix.
  2. Use valid semantic version.

Alpha 4 release for SmokeHTTP 2 - 2020-02-21 20:05:20

Visibility fix.

Alpha 3 release for SmokeHTTP 2 - 2020-02-20 00:56:12

  1. Add a MockInvocationTraceContext (#45)

Alpha 2 release for SmokeHTTP 2 - 2020-02-19 20:51:18

  1. Downstream service call tracing (#43)

Alpha 1 release for SmokeHTTP 2 - 2019-11-06 23:45:42

  1. Adopt SwiftLog 1, passing the logger explicitly (#31)
  2. Adopt SwiftMetrics 1 and record invocation metrics (#32)
  3. Adopt Swift.Result rather than our own Result types. (#29)
  4. Expose the http response code when throwing client errors (#33)
  5. Move SwiftNIO dependency to major version 2 (#35)
  6. Remove compatibility for Swift versions prior to 5 (#28)
  7. Client waits during connecting (#25)

Remove compiler warnings under Swift 5.x - 2019-10-01 17:46:37

Remove compiler warnings under Swift 5.x

First official release of SmokeHTTP - 2019-04-04 15:57:49

This release of SmokeHTTP provides compatibility with Swift 4.1 and Swift 4.2 using SwiftNIO 1.x.

Handle response more efficiently - 2019-04-02 00:25:19

Implement a number of internal fixes to be more efficient in memory usage, including using NIOFoundationCompat to convert directly from a ByteBuffer to Foundation.Data when receiving the response in HTTPClient.

Add a key transform strategy for encoding and decoding shapes. - 2019-03-26 22:56:55

Add a key transform strategy for encoding and decoding shapes with a passthrough option, an option to capitalise and de-capitalise the first character and a custom transform. This is enable use cases where there is a known mapping from the Codable instance to the serialised form that cannot be fully expressed as CodingKeys (the mapping is different in different circumstances.

Fix crash on Linux branch of getRetryInterval() - 2019-03-13 18:00:09

Fix crash on Linux branch of getRetryInterval().

Fixed a crash in client retry logic - 2019-03-12 21:07:27

Fixed for a fatal error when the retry configuration as 0 as the upper bound retry duration.

Fixed two issues with exponential retries. - 2019-02-26 01:00:32

  • Fixed an issue where async retries where both initiating a retry request and calling the completion handler
  • Fixed an issue where retry intervals where not being calculated correctly.

Add support for exponential backoff retries in HTTPClient - 2019-02-12 17:24:36

Added entry points to HTTPClient that will automatically handle request retries with exponential backoff-

  • HTTPClient.executeSyncRetriableWithOutput()
  • HTTPClient.executeSyncRetriableWithoutOutput()
  • HTTPClient.executeAsyncRetriableWithOutput()
  • HTTPClient.executeAsyncRetriableWithoutOutput()

Note: This is also a release-candidate for 1.0.0.

Another Internal refactor of HTTPPathDecoder - 2019-01-24 01:25:04

Move logic to get a Shape related to a template. This allows for cleaner determination if a http path conforms to a template.

Internal refactor of HTTPPathDecoder - 2019-01-04 15:18:46

Allow higher level components to decode a path into a Shape seperate to decoding it into a Swift type.

More Coders and HTTPClient improvements - 2018-12-19 20:00:12

This release is moving the library closer to finalized APIs for version 1.0. It has some breaking changes-

  • The execute*WithOutput APIs of HTTPClient now produce an instance conforming to HTTPResponseOutputProtocol. This is analogous to the input type HTTPRequestInputProtocol for these methods and provides access to decoded headers from the response.
  • The HTTPClientDelegate.getTLSConfiguration() function now returns an optional TLSConfiguration. If nil is returned, a client will use http rather than https.
  • The QueryCoder package has been moved to QueryCoding.
  • The HTTPClient now needs to be explicitly closed using the close() API. The wait() can be used to block until the client is completely shut down. This was a recommendation from the SwiftNIO team (@weissi).

The are also some additions-

  • The QueryCoder (now QueryCoding) package has been joined with HTTPHeadersCoding and HTTPPathCoding for encoding/decoding headers and paths respectively.
  • The HTTPClient can now be used with an existing EventLoopGroup; it may be more efficient for an application to share ELGs across clients and/or other components. This was also a recommendation from the SwiftNIO team (@weissi).