Skip to content

Conversation

@StefanPrintezis
Copy link

@StefanPrintezis StefanPrintezis commented Jun 20, 2025

Summary

This PR implements a protocol-based testing approach inspired by Soto's AWSHTTPClient pattern, making AppStoreServerAPIClient conform to Sendable, and improves the overall architecture for better testability and concurrency safety.

Protocol-Based HTTP Client Architecture

  • Added AppStoreHTTPClient protocol for abstracting HTTP operations
  • Made HTTPClient conform to AppStoreHTTPClient by extension
  • Updated AppStoreServerAPIClient to accept any AppStoreHTTPClient for dependency injection & sharing the http pool
  • Exposed httpClient through initializer with HTTPClient.shared as default so we share the http pool by default
  • Removed manual deinit since HTTP client lifecycle is now managed externally

Configuration Improvements

  • Created AppStoreServerAPIConfiguration struct for centralized configuration management
  • Added throwing configuration initializer for better error handling
  • Non-throwing client initializer for cleaner API usage

Testing

  • Implemented MockHTTPClient for unit testing, since we couldn't extend the final Sendable class anymore
  • Updated test suite to use protocol-based mocking instead of inheritance

Documentation Updates

  • Updated README to use new configuration-based syntax
  • Fixed variable name inconsistencies in code examples

Instead of initializing a http client pool, expose the httpClient through the initializer or default on .shared that way we can share the http pool with others
Deinit is no longer needed since httpclient is exposed
Create a configuration struct so we are able to throw when initializing config & have a non throwing client initializer
…it tests, since AppStoreServerAPIClient is a final Sendable class now
@StefanPrintezis StefanPrintezis changed the title Sp/sendable client Implement Protocol-Based Testing with Sendable Conformance in AppStoreServerAPIClient Jun 20, 2025
@StefanPrintezis StefanPrintezis marked this pull request as ready for review June 20, 2025 08:41
// try! used for example purposes only
let client = try! AppStoreServerAPIClient(signingKey: encodedKey, keyId: keyId, issuerId: issuerId, bundleId: bundleId, environment: environment)
let config = try! AppStoreServerAPIConfiguration(signingKeyPem: encodedKey, keyId: keyId, issuerId: issuerId, bundleId: bundleId, environment: environment)
let client = AppStoreServerAPIClient(config: config)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is breaking out the configuration necessary for Sendable conformance? Why was this change made

transactionHistoryRequest.sort = TransactionHistoryRequest.Order.ascending
transactionHistoryRequest.revoked = false
transactionHistoryRequest.productTypes = [TransactionHistoryRequest.ProductType.autoRenewable]
let transactionHistoryRequest = TransactionHistoryRequest(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unrelated to to the proposed changes in this PR

}

public enum APIResult<T> {
public enum APIResult<T: Sendable>: Sendable{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the only change in this PR necessary to actually make this Sendable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants