Stop using the HttpClient the wrong way in .NET

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody i'm nikki and in this video i'm going to clear out any misconceptions you might have on how to properly use the httpclient in dotnet every now and then i'm going to use it in a video and there will be comments saying you should not be doing that that is not the best practice but the truth is all the suggestions they have are outdated advice that actually has bugs in them and i have to remove those comments because i don't want people to see them and actually follow them so in this video we're going to clear all that once and for all if you like a lot of content and you want to see more make sure you subscribe bring the some notification bell and for more training check out nickchopsters.com now just a quick reminder before i show you the code i want to let you know that we'll be running my two-day in-person workshop introduction to effective testing in c sharp and net in a few conferences this year that is ndc oslo ndc sydney dotnet days in romania ndc minnesota and ndc london and probably more after that but for now those are the days so if you want to spend a couple of days with me and set the right fundamentals for your testing practices then check them down below so let me show you what i have here so i have a project over here which has a weather forecast controller injecting the iweather client and this service actually has a real client calling the open weather client from the open weather map api with a real api key which by the time you watch this video will be invalidated so don't even bother and very quickly what this does is i expose an endpoint that allows the users to specify the city so i can say for example london here and i can get the weather as you can see i can get a bunch of different things like time zone name id then the wind speed and that's the current weather and then like temperature in um that's not fahrenheit is it uh is it kelvin well it's definitely a temperature and if i for example here say paris then i'm gonna get the paris one in france and so on and so forth that's the main idea and the reason why i'm using that example is because this client is using an http client to call the open weather map api now what you can see here is me using a new http client pair request and then i'm using the using keyword because http client is actually implementing the message invoker which is implementing i disposable and people know that if there's an ids possible then you should dispose it well this is not true with the http client and if you're doing this you will probably encounter at some point if your traffic increases circuit exhaustion and thankfully most people know that and the fix for that is fairly easy the recommendation that people have is to actually reuse the http client and that is correct you can go ahead and say private read only http client and have your http client be initialized here and i can copy that instantiation actually exactly as it is and then if i do that and i use that http client over here and i comment that out then i don't need this either then this will work fine and because my code registers that open weather client as a singleton it is the same http client instance that's going to be reused not only preventing us from getting socket exhaustion but actually offering better performance in fact you can see i have 15 milliseconds here while before i had more like 40 and you might have seen this in a different iteration because if this client is actually transient on scoped you don't want to create a new client every time through the class then some people make a static read-only client and then they reuse that static line which will be the same instance no matter how many times you instantiate this class and this will also work and actually give you the exact same benefits every single time so if you're doing that you're on the right track however what most people don't know is that with this approach of a singleton http client your code is suffering from a dns issue because if the dns ttl is expired and the domain name now points to a new iep your code will never know until it restarts because there is no logic by default in the http client to handle that what you could do to handle that is something like this you can have a new socket http handler and if you go ahead and you set the pulled connection lifetime property then you can set that to a value that reflects dns changes i can say like for from minute one and this will actually solve the problem if you want to deal with it in a singleton fashion however this is still not the recommended and best way to go about it what you want to do instead is use the i http client factory and that is the best way you can solve this problem for a few reasons which i'm going to explain now so how do you use that well there's actually a few ways you can do this but i'm going to show you what i think is the simplest way by default and all you need to say is in your program.cs or your startup you want to say services.add http client and in this case because i'm injecting it in the openweather client through the iwata client registration i'm going to use the same services here so i'm going to say add an http client in there and the great thing about this is because that client is specific to that thing i can say client dot and i can set all of my things like the base address for example in there so now it is pre-configured and i don't have to deal with it in here and now all i need to say is private read-only http client and i can simply inject it here and now all i want to do is use it there and then if i run this code what i want to show you is i want to use a few break points here is when i run this now and i hit the breakpoint you can see the client exists and it already has that open weather map api url because it is that pre-configured http client and then it goes in here it gives me the response and i can see the response over there and this is very very efficient and the reason why this is the recommended way to do things is because what's going to happen is this http client is actually transient but the handler behind the scenes which is what truly is doing the heavy lifting and is calling those apis is actually pulled and managed by the http client factory and it gives you a client with a reused handler which makes it very very efficient and it fixes that dns issue we can actually dive deeper in here in the program.cs and show you exactly how that happens so what i have is the add http client and it's going to add it in the di and then we're going to see it as logging ads options adds a bunch of stuff and then it registers an http message handler builder which is what is actually sending the request and then a default http client factory and then it is wiring it up to return that over here and if we see what's in here you will see that there's actually a bunch of stuff but the important thing is the create client method because that is what is giving you back that new http client so what's happening is the code comes in here it tries to find the handler from the cached handlers you can see them here the active handlers if it exists then it gives it back if it doesn't exist it puts it in there and gives it back and you get back the http message handler and then you're creating an http client over here with that handler which is marked as non-disposable because we want to reuse the handlers because they're pulled and then we give the options back of the factory which is what that thing over here will effectively be so that is being respected as well and then we're returning that client and that is why this is the most efficient way to do this because the heavy object that is prone to be dodgy is actually cached in memory pulled and reused and then the client itself which is a very relatively thin object that just has instructions on how to use all its downstream components is just instantiated every time and if you want to dispose it you can and then there's a factory for the handler that is also registered over here and that's it and that is what's called in the http client factory world the typed client you define that http client to be resolved with a specific type however it's not the only way you can do this you can also have for example a named client you can say that okay i don't define a type but i say that this is my weather api client and you can do that too and the way this works is instead of actually injecting the client directly you can go ahead and say private read only i http client factory and inject the http client factory here and then say client equals http clientfactory.createclient and pass down the name weather api and then that client can be used and actually i should definitely comment this thing out and with that thing commented out this is absolutely fine all the rules the same rules will be respected and you're just resolving it by name and you return the exact same thing so very efficient reused handlers and it's very nice if you want to have different clients in the same call and you don't want to inject three things named http client because it's not explicit which client you're getting so in that way it's also a cleaner way to do things and actually another reason why isotopic line factory is amazing is it's awesome integration with a library called poly which in case you don't know i've talked about it in the past is where you're gonna spend most of your time if you're writing code that calls other apis because you want those calls to be resilient and probably can give that resilience so please subscribe if you want to see more on how to use poly and how painless the process can be with that library but what do you think were you using those practices were you using the i http client factory correctly were using a singleton http client what was the approach you were using leave a comment down below well that's all i had for you for this video thank you very much for watching special thanks to my patreons for making this videos possible if you want to support me you're going to find the link in the description down below leave a like if you like this video subscribe and click on the like sharing the bell as well and i'll see you in the next video keep coding
Info
Channel: Nick Chapsas
Views: 151,125
Rating: undefined out of 5
Keywords: Elfocrash, elfo, coding, .netcore, dot net, core, C#, how to code, tutorial, development, software engineering, microsoft, microsoft mvp, .net core, nick chapsas, chapsas, dotnet, .net, httpclient, httpclientfactory, httpclient c#, httpclient c# json, ihttpclientfactory, Stop using the HttpClient the wrong way in .NET
Id: Z6Y2adsMnAA
Channel Id: undefined
Length: 10min 14sec (614 seconds)
Published: Mon Aug 15 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.