HttpClient - The Correct way to Use + Code Review

  Рет қаралды 10,883

Shiv Kumar

Shiv Kumar

Күн бұрын

Пікірлер: 59
@VinuP2023
@VinuP2023 4 жыл бұрын
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 KZbin space delivers this top notch content. 🙏☺️
@Matlus
@Matlus 4 жыл бұрын
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 жыл бұрын
@@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.
@kiranb5603
@kiranb5603 3 жыл бұрын
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
@mmreddys5195
@mmreddys5195 4 жыл бұрын
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. 🙏
@boris.stanojevic
@boris.stanojevic 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 3 жыл бұрын
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/MovieServiceKZbin
@saurabhchauhan232
@saurabhchauhan232 4 жыл бұрын
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 жыл бұрын
@UCH6ldY4aBH_Qn5pOXDgFl8w You can use GitHub and/or Gist (via GitHub) to publish code and them message to directly from KZbin to let me know the link
@saurabhchauhan232
@saurabhchauhan232 4 жыл бұрын
@@Matlus kzbin.info/www/bejne/eaWrlIdrjcSlj7M 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
@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.
@COCSparky
@COCSparky 4 жыл бұрын
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 жыл бұрын
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 жыл бұрын
​@@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 жыл бұрын
@@COCSparky I hear you!. The guidance is clear though. Always use ConfigureAwait(false) :)
@niteeshyarra5348
@niteeshyarra5348 3 жыл бұрын
@16:07 you could do Ctrl + R + R on the param name to rename at all places
@Matlus
@Matlus 2 жыл бұрын
Good point!
@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?
@sumitmore4680
@sumitmore4680 4 жыл бұрын
Excellent video Shiv like always ! 👍🏻
@Matlus
@Matlus 4 жыл бұрын
Thank you Sumit!
@vinays4757
@vinays4757 4 жыл бұрын
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 жыл бұрын
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 жыл бұрын
@@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 жыл бұрын
@@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 жыл бұрын
@@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
@justsomeguy_93
@justsomeguy_93 4 жыл бұрын
“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 жыл бұрын
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.
@kiranmarturu1095
@kiranmarturu1095 3 жыл бұрын
Thank you shiv, this helped me a lot.
@TheChandan0285
@TheChandan0285 4 жыл бұрын
You are Guru Shiv thanks for posting
@Matlus
@Matlus 4 жыл бұрын
You're welcome Kumar!
@gladiator2017
@gladiator2017 4 жыл бұрын
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 жыл бұрын
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 жыл бұрын
@@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.
@galaxiegalaxie5003
@galaxiegalaxie5003 4 жыл бұрын
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
@gurdeepgss
@gurdeepgss 2 жыл бұрын
👌🏾
@bose100989
@bose100989 4 жыл бұрын
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!
@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.
@elijahbokman7694
@elijahbokman7694 3 жыл бұрын
i didnt understand anything you said sry :(
@elijahbokman7694
@elijahbokman7694 3 жыл бұрын
me nwither
@Matlus
@Matlus 3 жыл бұрын
@@elijahbokman7694 me neither:)
Design Nugget - Builder Pattern - C# Expressions
57:05
Shiv Kumar
Рет қаралды 1,9 М.
黑的奸计得逞 #古风
00:24
Black and white double fury
Рет қаралды 27 МЛН
VAMPIRE DESTROYED GIRL???? 😱
00:56
INO
Рет қаралды 9 МЛН
Osman Kalyoncu Sonu Üzücü Saddest Videos Dream Engine 275 #shorts
00:29
IDisposable Exposed
53:48
Shiv Kumar
Рет қаралды 3,3 М.
Stop using the HttpClient the wrong way in .NET
10:14
Nick Chapsas
Рет қаралды 194 М.
Middleware Pattern For HttpClient With Delegating Handlers
17:07
Milan Jovanović
Рет қаралды 15 М.
The Secret HttpClient Feature You Need To Use in .NET
10:41
Nick Chapsas
Рет қаралды 73 М.
To LINQ Or Not To LINQ - That is the Question
32:35
Shiv Kumar
Рет қаралды 3,3 М.
30 Programming Truths I know at 30 that I Wish I Knew at 20
17:41
So You Think You Know C#? Delegates & Higher Order Functions
53:36
Brutally honest advice for new .NET Web Developers
7:19
Ed Andersen
Рет қаралды 226 М.
You Are Using HttpClient Wrong
9:06
Codewrinkles
Рет қаралды 4,2 М.