HttpClient - The Correct way to Use + Code Review

Поделиться
HTML-код
  • Опубликовано: 7 фев 2025

Комментарии • 59

  • @VinuP2023
    @VinuP2023 4 года назад +12

    Shiv, today is Guru poornima as per Hindu mythology. What better day to show gratitude to Guru like you. I'm grateful to you for all your efforts. :)
    I can say with confidence no one in programming RUclips space delivers this top notch content. 🙏☺️

    • @Matlus
      @Matlus  4 года назад +5

      Thank you for your kind words Vinay. I appreciate the encouragement and am truly humbled. I am but a student of this craft.🙏

    • @UPSCCSE-ku7ej
      @UPSCCSE-ku7ej 4 года назад +1

      @@Matlus Awesome work buddy ....Great accent

    • @Matlus
      @Matlus  4 года назад

      @@UPSCCSE-ku7ej Thank you!

  • @Telee_Pawt
    @Telee_Pawt 2 года назад

    I've struggling for days now trying to refactor an existing solution to the factory model and gave up. Your solution is what I'll be adopting. This, I can get my head around. Thanks so much.

  • @saurabhchauhan232
    @saurabhchauhan232 4 года назад +3

    I hope this series will continue ! A fanboy moment Sir, I have learned a lot from you🙏, God bless you ❤️

    • @Matlus
      @Matlus  4 года назад

      Thank you Saurabh! 🙏. If you have questions, or scenarios that I can answer by way of a video, please do let me know. If you'd like to send me code I can review it (anonymously of course) as a part of the video too.

    • @Matlus
      @Matlus  4 года назад +1

      @UCH6ldY4aBH_Qn5pOXDgFl8w You can use GitHub and/or Gist (via GitHub) to publish code and them message to directly from RUclips to let me know the link

    • @saurabhchauhan232
      @saurabhchauhan232 4 года назад

      @@Matlus ruclips.net/video/CtHcT5X_rYQ/видео.html line number 107, also need to be using right because, it's httprespone disposable?
      line number 114 MemoryStream also right? (just learning from you hope I am correct )

    • @Matlus
      @Matlus  4 года назад

      @@saurabhchauhan232 I'm not sure where is in the video you're pointing to exactly. Can you give me the time on the video I should be looking at?

    • @saurabhchauhan232
      @saurabhchauhan232 4 года назад

      @@Matlus 47:45 . Sorry I thought above link is working I copied with current time not sure why it didn't work I must have done something wrong

  • @mmreddys5195
    @mmreddys5195 4 года назад +1

    One of the best videos & an incredible explanation to apprehend http client concept. Shiv is gem & technical expert who always translate complex stuff into simple way. Shiv is unmatchable & brilliant mentor 👍👍👍

    • @Matlus
      @Matlus  4 года назад

      Thank you Malla. Appreciate the kind words!. I am truly humbled. 🙏

  • @COCSparky
    @COCSparky 4 года назад +1

    Great content Shiv! I recently found a 'nugget' working on an ASP.NET Core Blazor project. Blazor has thrown a monkey wrench in the blanket statement "You do not need to use ConfigureAwait(false) in an ASP.NET Core application." Blazor is part of ASP.NET Core, and has a synchronization context!

    • @Matlus
      @Matlus  4 года назад +1

      Hi Adam, Thank you.
      > Blazor is part of ASP.NET Core
      True and false. It is not an ASP.NET Core application. It's is a .NET Core application, that runs in the memory space of the browser. It is used in tandem with an ASP.NET Core application. Hope that makes sense?

    • @COCSparky
      @COCSparky 4 года назад +1

      ​@@Matlus agreed! Blazor has two hosting models, server-side and client-side (WASM). I believe that server side Blazor is an ASP.NET Core application yes? Since the server renders, and then sends the DOM diff to the client via SignalR. Oh, and just to vex us, you can also run client side WASM app hosted by an ASP.NET Core application (but it's still not running in the context of an ASP.NET Core application, as you pointed out)

    • @Matlus
      @Matlus  4 года назад +1

      @@COCSparky I hear you!. The guidance is clear though. Always use ConfigureAwait(false) :)

  • @niteeshyarra5348
    @niteeshyarra5348 3 года назад +1

    @16:07 you could do Ctrl + R + R on the param name to rename at all places

    • @Matlus
      @Matlus  3 года назад

      Good point!

  • @kiranb5603
    @kiranb5603 3 года назад +1

    Hi Shiv it was very nice talk and is really helpful.
    But I can't agree on the way in which you are using HttpClient. Even if you are reusing the client inside a class you are not re-using it in the application lifecycle, which is needed to avoid socket exhaustion. Suppose your WorkOrderServiceGateway or WorkOrderServiceGatewayV2 is called from a controller methods and you get 100 concurrent calls, your application creates 100 HttpClientHandler and it disposes all of that without reusing within different requests. A disposed HttpClient connection will wait again for 240 secs to completely removed. Server will issue socket exhaustion exception in heavy traffic.
    The best approach is to implement a caching mechanism for HttpClientHandler(but no need to re-invent the wheels) or use HttpClientFactory.
    Note: Please dont use static HttpClient as it won't respect DNS changes

  • @robbiedevine8518
    @robbiedevine8518 2 года назад

    Password as clear text string is an issue, since GC is non-deterministic, thus can linger in memory. Was this just a quick mock? SecureString and char[] are the 2 ways I've seen this done. Just curious. Love the vids btw. Keep it up.

  • @boris.stanojevic
    @boris.stanojevic 4 года назад +3

    Hi Shiv, I recently found your channel and I'm simply fascinated by the content.
    I have a question regarding the WorkOrderServiceGateway and would appreciate it if you could explain it a bit or direct me to any appropriate resources.
    What is the reason for making WorkOrderServiceGateway be of IDisposable type and then manually disposing resources?
    Is the reason behind that the fact that you made HttpClient a field in the class?
    Thanks in advance.

    • @Matlus
      @Matlus  4 года назад +1

      Hi Boris, thank you and I'm glad to hear you're enjoying the content!
      Yes, typically, you don't wan to create an instance of an HttpClient for each time you want to make an Http request (so you shouldn't be using the "using" clause). Thus the HttpClient is a member of the class. But it does need to be dispose. So the class needs to implement the IDisposable interface. Effectively, this (the need to implement IDisposable) could potentially go up the call chain.
      I have an sample project on my GitHub you can take a look at that uses a similar Gateway. You may want to study the entire call chain to see what's going on. Essentially you'll see that the Gateway is also created just once in the lifetime of the application.
      github.com/matlus/MovieServiceRUclips

  • @kiranmarturu1095
    @kiranmarturu1095 3 года назад

    Thank you shiv, this helped me a lot.

  • @sumitmore4680
    @sumitmore4680 4 года назад +1

    Excellent video Shiv like always ! 👍🏻

    • @Matlus
      @Matlus  4 года назад

      Thank you Sumit!

  • @vinays4757
    @vinays4757 4 года назад +1

    Hi Shiv,
    Thanks for the amazing playlist . Demonstrating the approach of PWI. It was a good learning experience. Regarding httpclient class, what's your opinion on making httpclient as a singleton or a static property to reuse the instance.?

    • @Matlus
      @Matlus  4 года назад +1

      You can't make it a singleton. You could encapsulate it within a class that is a singleton. I don't see a problem with either (singleton or static member variable). HttpClient is multi-thread safe, that is the same instance could be used to make multiple HTTP calls simultaneously from multiple threads. The problem/concern would be that the rest of the code needs to be written correctly (understanding statics as well as thread-safe). Essentially that boils down to not maintaining state.
      In my case, typically the class that uses the HttpClient (The Gateway) is used like a singleton. That is, I create one instance of it and then for the lifetime of the application, I use the same instance. The Gateway is not inherently a singleton, but it's used as such.

    • @vinays4757
      @vinays4757 4 года назад +1

      @@Matlus Thank you Shiv for sharing your view. There are many blogs out there hinting that a single instance of httpclient may cause DNS issues. But as you hinted, if encapsulating code is singleton & rest of the code is written correctly (service not maintaining the state), then I do not see a problem either.

    • @Matlus
      @Matlus  4 года назад +1

      @@vinays4757 The DNS issue can still occur. But that's only if you're site's IP Address changes. Typically in the cloud you could deploy say an new release of your app to your staging site (different IP address) and then swap the DNS entry to point your production domain to the staging site (IP Address), making it the production sites while the earlier production site becomes the new staging site. Hope that makes sense.?

    • @vinays4757
      @vinays4757 4 года назад

      @@Matlus exactly. That's valid. I've a use case. There's a health check library, say to test the availability of a NoSQL DB. URL endpoint is passed as an environment variable. NoSQL DB client has two parameters; one which takes endpoint URL n another parameter takes httpClient object(stateless). Change in DNS translates to change in endpoint parameter. So the endpoint is not baked into httpclient object from call site. Since httpclient is not dependent on any environment variables, I felt DNS changes will not affect my use case.

    • @Matlus
      @Matlus  4 года назад +1

      @@vinays4757 I don't know what you mean by "change in DNS". A change in a DNS record entry could take anywhere from 24-48 hours for all root name servers and caches to reflect the change. So unless you're using the IP address (instead of a domain name) you'll still likely have the DNS related issue.
      Your best bet would be to create a new instance of an HttpClient each time a DNS change occurs (if you're able to be notified of the DNS change) and send that new instance to the NoSQL DB Client method

  • @TheChandan0285
    @TheChandan0285 4 года назад +2

    You are Guru Shiv thanks for posting

    • @Matlus
      @Matlus  4 года назад

      You're welcome Kumar!

  • @EMWMIKE
    @EMWMIKE 2 года назад

    why is the httpclient disposed? Makes no sence, always tought it would be static. If I would use that code in my work with 20K transactions per minute I would end up with socket exhaustion within a few minutes.
    Just because the httpClient is disposed doesn't mean the Operating system has forgot about it.
    Or is the httpClientFactory not really disposing it?

  • @gurdeepgss
    @gurdeepgss 2 года назад +1

    👌🏾

  • @gladiator2017
    @gladiator2017 4 года назад +2

    Hi Shiv, thank you for this wonderful video. I really love the way you describe "programming with intent” and the need for having discipline with naming class, parameters, using internal sealed, readability with orchestration etc. After going through many of your videos, I am becoming verbose when I define names of properties, params 😊 (eg:- I define http timeout variable as OverallHttpClientTimeoutInMilliSeconds since I also have polly per request time out in our code. It may sound odd sometimes 😊)
    About this video on http client, I have few things we use in our project which I would like to share and want to understand your opinion on those.
    Using httpclient factory - We use dotnet core > 2.1 in our projects and we have been recommended to always use httpclient factory + typed http client (as recommended by microsoft )
    docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests
    We have been bitten by socket exhaustion problem in past and using a singleton httpclient is a no go since it will cause dns cache issues and our system is geo replicated system with active/passive failover configuration. Even if we use IDisposable on httpclient , as per Microsoft doc its not going to reduce socket issues as underlying socket is not disposed immediately. With httpclient factory, your handler chain is reused with specific life time (I think it is 2 minutes default and will reuse same ip/ephermal port for the outbound call). So, we register the typed http client in the startup and use DI to inject the httpclient to specific client (say FooServiceClient) which is a typical pattern which microsoft recommends in its dotnet core documentation (I know you are not a big fan of DI, me either 😊). Also, we define 2 outgoing delegating handlers for Correlation id and Request timing as standard across all our outbound calls.
    So, I would like to understand if we have any other alternative pattern (other than DI+Register as typed client which Microsoft recommends in its documentation) so that we get same benefit of reusing the httphandlers in httpclient.
    Also, I would like to see how to hook up polly library with httpclient with error response handling included. I made it work of error response handling (getting the actual response body from upstream after the final retry completed), but it’s not quite elegant as I would like. I achieved that with a fallback policy which again is not the correct way to do that as find it executed on every retry failure of that request which is not I want.
    IAsyncPolicy wrapOfRetryAndFallback = Policy.WrapAsync(fallbackPolicy, httpWaitAndRetryPolicy);
    private static Task FallbackAction(DelegateResult responseToFailedRequest, Context ctx, CancellationToken cancellationToken)
    { Console.WriteLine("Fallback action is executing");
    return Task.FromResult(responseToFailedRequest?.Result);}
    I would like to understand how you are using polly retry library in your projects with httpclient.
    While using httpclient sendasync, we always wrap it in try catch with explicitly catching HttpRequestException (HttpRequestException httpRequestException) since there is a chance that you may get dns errors or other connection issues.
    var httpResponse = await _httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false)
    Also as a standard practice in our systems, in the case of upstream error responses with body, upstream always send a concrete type (json payload with errorcode, substatus code, messages etc) and we try to deserialize the error payload to concrete type(ReadFromJsonAsync) and always have a json exception catch block incase if upstream alters the response payload type/params.
    One last thing, on using new Uri() - Our senior leads/experts advised us to use UriBuilder when dealing with upstream http calls rather than new Uri, since it will properly encode your path, query parameters and you will get a proper final URI.

    • @Matlus
      @Matlus  4 года назад +1

      Hell Shine, Thank you for your well thought out comment. There are a lot of questions in here....
      You can (And should) use the HttpClientFactory and you can use it without DI. It's just a class. In fact you can use HttpClientFactory in a .NET Framework application since it is a .NET 2.0 Standard library.
      I've not had the need to use poly in any production work, so I'm not the best person to provide you with an answer.
      If you're experiencing exceptions when calling SendAsync, then you you should wrap a try-catch, but only to translate to a custom exception and throw. Please don't swallow exception or translate to bool returns. Have you had a DNS issue? It should only occur if you're swapping the IP the domain points to. HttpClientFactory will continue to improve in this regard so continue to use HttpClientFactory.
      I don't build Uris on the fly, so I haven't had a need to build Uri. You should only need to use the UriBuilder is you're "building" URIs on the fly. In my case the "base" url is always know and generally in a config file or database. The only thing the application does is tags on the tail of the url.

    • @Matlus
      @Matlus  4 года назад

      Sorry, as regards using HttpClientFactory.... use can use it without injecting it. That is you can use the DI framework to provide you with instances but you don't have to inject it. Hope that makes sense?
      I don't believe one can use the HttpClientFactory without using the DI framework of .NET Core.

    • @gladiator2017
      @gladiator2017 4 года назад +1

      @@Matlus Thank you for your response. We haven't face DNS issues in prod, but we write test cases for those scenarios and ensure its handled with proper logging and our system is a geo replicated one with active/passive failover using Azure Trafficmanager. Also it covers any other transient network failures and make sure it gets logged properly . Yes, using UriBuilder in the sample code you shared may be an over kill since the url is not constructed and always remains the same. Yes we are sending custom exceptions back to caller after handling specific exceptions.

  • @justsomeguy_93
    @justsomeguy_93 4 года назад +3

    “Don’t go thinking this is just a prototype, next thing you know that prototype code has landed itself in production”...it’s like he knows🤯😨😱

    • @Matlus
      @Matlus  4 года назад +2

      LOL! Been there, done that. But in those days, I didn't differentiate between prototype and production code. Bang it out and if it works, it's good to go. Over the years, I've matured and have a lot of scare wounds to show for it.

  • @galaxiegalaxie5003
    @galaxiegalaxie5003 4 года назад +1

    Could you do some video about blazor webassembly thank you😁

    • @Matlus
      @Matlus  4 года назад

      GaLaXie, I'm afraid I don't have enough experience with Blazor to make a video on it. Sorry

    • @galaxiegalaxie5003
      @galaxiegalaxie5003 4 года назад

      @@Matlus no problem, may be some day in future😁,also please give us some of your opinion about dapper and entity framework etc

  • @MrMaxKovtun
    @MrMaxKovtun 4 года назад

    // TODO: PWI: Async method should receive CancellationToken parameter
    Thank you for video :)

    • @Matlus
      @Matlus  4 года назад

      :) sure, if a cancellation token is available/being used.

  • @bose100989
    @bose100989 4 года назад +1

    Hi Shiv, you are a hidden gem I would say. Excellent content. I completely agree on the usage of HttpClientFactory. Not only it would help in reusing the httpClients but also will be beneficial in dealing with issues related to dns refresh - github.com/dotnet/runtime/issues/18348

    • @Matlus
      @Matlus  4 года назад

      Thank you for your kind words Abhishek!

  • @elijahbokman7694
    @elijahbokman7694 4 года назад +1

    i didnt understand anything you said sry :(