checkout / checkout-sdk-net

Checkout SDK for Microsoft .NET
https://checkout.com
MIT License
20 stars 21 forks source link

SDK Documentation advice for .NET Framework usage when using custom HttpClientFactory #346

Closed Antaris closed 7 months ago

Antaris commented 10 months ago

Hi,

I've been integrating the new platform and have come across a little gotcha. I use a custom HttpClientFactory so I can intercept the creation of the underlying HttpClientHandler for logging purposes.

On .NET Framework, the best practice around using HttpClient is to re-use it, and not dispose and keep recreating it, as it is already re-entrant and thread safe. To this end, in my custom HttpClientFactory, I was holding onto a single instance of HttpClient, however due to how the CheckoutSDK initialises many clients for the various APIs, it means the HttpClient.BaseAddress property picks up the last configured client, meaning when I make requests to the PaymentsClient, it'll actually pick up the https://transfers.checkout.com base address as this was configured last.

This could be treated as a bug in that you could be explicit on the URLs being sent by requests instead of using the BaseAddress property, however I think this could largely be mitigated with some CheckoutSDK documentation guidance around the use of custom HttpClientFactory

armando-rodriguez-cko commented 10 months ago

Thank you @Antaris. You are right. We have pending make this improvement (bug). We will try to resolve it soon, we take note.

Antaris commented 10 months ago

I'm happy to submit a PR for this, depends the approach you want to take?

armando-rodriguez-cko commented 10 months ago

Thank you @Antaris! All PR is welcome, of course, the focus will always be to maximize the needs and compatibility of all SDK users without breaking changes wherever possible.

Marfusios commented 10 months ago

Good issue, would be great to have it fixed. Currently, I had to create a custom proxy:

using System.Net.Http;
using ICheckoutHttpClientFactory = Checkout.IHttpClientFactory;

namespace ZapMiddleware.CheckoutAdapter.Infrastructure.External;
internal class CheckoutHttpFactory : ICheckoutHttpClientFactory {
    public const string HttpClientName = "CheckoutClient";
    private readonly IHttpClientFactory _httpClientFactory;

    public CheckoutHttpFactory(IHttpClientFactory httpClientFactory) {
        _httpClientFactory = httpClientFactory;
    }

    public HttpClient CreateClient() {
        return _httpClientFactory.CreateClient(HttpClientName);
    }
}

And configure via builder:

return CheckoutSdk.Builder()
    ...
    .HttpClientFactory(httpFactory)
    .Build();
Antaris commented 8 months ago

@armando-rodriguez-cko PR submitted: https://github.com/checkout/checkout-sdk-net/pull/364

armando-rodriguez-cko commented 7 months ago

Thank you @Antaris! We will review a soon as possible.