The RIGHT Way To Use HttpClient In .NET

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

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

  • @MilanJovanovicTech
    @MilanJovanovicTech  Год назад +21

    Get the source code for this video for FREE → the-dotnet-weekly.ck.page/httpclient
    Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
    Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt

    • @balakrishnan-gf9rw
      @balakrishnan-gf9rw Год назад

      Hi Milan, I have a correlation Id in my web api. I used typed http client in mvc core 6 application. So in that case how to pass x-correlation Id in all my web API from client. Kindly suggest me..

  • @davearkley7014
    @davearkley7014 Год назад +20

    I've been using named clients, but like the idea of strongly typed clients so may try them out. One advantage of being able to apply configuration once is that you can add Polly retry policies and they will be used for all instances of the named/typed client.

  • @hamitkarahan2973
    @hamitkarahan2973 Год назад +3

    Last part was very nice Milan. Many thanks. I preferred named clients many times in projects. I didn't prefer typed clients because I was a little afraid to delve into this lifetime issues when my services are singleton. I am just basically calling CreateClient method in my infra layer with a using() block. This approach didn't give me any problem so far in production.

    • @PippiTheLongSock
      @PippiTheLongSock Год назад

      I think you shouldn't manually dispose the instance. I am pretty sure the framework does that automatically.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      I agree, if it works don't fix it. Right?

    • @hamitkarahan2973
      @hamitkarahan2973 Год назад

      @@MilanJovanovicTech Yesss 😁

  • @mylesdavies9476
    @mylesdavies9476 Год назад +2

    Nice, have been working with typed clients for a while and find it to be a good approach. The only thing I do differently is inject configuration into the typed client and assign any required headers with the constructor, keeping the configure services nice and clean.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      I think it's better to do the common things inside of AddHttpClient

    • @mylesdavies9476
      @mylesdavies9476 Год назад

      @@MilanJovanovicTech fair enough, any particular reason?

    • @JUTO_MTL
      @JUTO_MTL Год назад

      I do exactly the same because i didnt figure out how to retrieve configuration with Option Pattern. I get null from the IConfiguration inside the HttpClient Configuration method. If someone have any idea

  • @michaelchudinov
    @michaelchudinov 4 месяца назад +1

    Well explained and practical oriented step by step tutorial. Thank you!

  • @Javilingys
    @Javilingys Год назад +1

    What about using Transient HttpClient service inside Scoped Services? Its ok?

  • @ImranAdam-h1p
    @ImranAdam-h1p Год назад +1

    Great Video Milan! Do you have a video showing how you would unit test this pls? (unit test IHttpClientFactory).

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      I don't yet, sadly. But I would take a look at MockHttp: github.com/richardszalay/mockhttp

  • @ershadnozari
    @ershadnozari Год назад +1

    You can inject a httpclientfactory instead of httpclient in a typed client to get around the singleton issue.

  • @johntotetwoo
    @johntotetwoo Год назад +1

    great video but I am wondering how you can configure with token that expires?

  • @diogosilva3637
    @diogosilva3637 Год назад +2

    Great explantion! Will you make a tutorial about Refit? Thanks!

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +3

      Perhaps, I like that library. Maybe to compare it with HttpClient

  • @WDGKuurama
    @WDGKuurama Год назад +1

    What i don't understand i why does it hate to make a new instance of the class injecting the httpclient if we could have a singleton do avoid being garbage collected all the time, is there issues with such techniques?

  • @d3vil5oldier
    @d3vil5oldier Год назад +2

    That's exactly what i was looking for, thanks Milan. Just one question, where do you think those typed clients belong to - Application layer or whatever?

    • @jaomartins1994
      @jaomartins1994 Год назад +1

      Infra

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +2

      HttpClient could lead you to place it in Infrastructure
      You could create an interface in Application, however

  • @VascoFernandesBuenoJunior
    @VascoFernandesBuenoJunior Год назад +1

    O think you need to make another video explaining how to add retry using Polly. I recomend to use Backoff.DecorrelatedJitterBackoffV2 in this case.

  • @haskell3702
    @haskell3702 Год назад +1

    Awesome explanation , but I have a doubt how can I Mock the http call using the typed approach?
    I mean, I want to write a test for GetByUserNameAsync method where the internal httpClient simulates returning 200 and a predefined json

  • @KhinSandarMyint-eq2ks
    @KhinSandarMyint-eq2ks Год назад +1

    May I know how to add dynamic certificate using HttpClientFactory ? I have to use different certs.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/methods-auto/httpclient/httpclient-addcertificate-method

  • @ALOKSHARMAMD
    @ALOKSHARMAMD Год назад +1

    you said using httpclient in traditional way can exhaust ports in long run, but is this true if we are doing proper dispose by applying using statements?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Yes - you'd end up creating too many handler instances. You want it to be long-lived

  • @JamesSecretofski
    @JamesSecretofski Год назад +1

    Thanks for the infiniteTimeSpan. Cool tip 👍

  • @palpie
    @palpie Год назад +2

    You should show the strongly typed version using an interface instead.

  • @Lazzerman42
    @Lazzerman42 Год назад +2

    Thanks! Very well explained and clear code examples! I use the RestSharp for know - because it has support for oAuth1(I need it for an old smartHome device). Are there any helpers for oAuth1 and HttpClient?

  • @toragodzen
    @toragodzen Год назад +2

    Hi, great video! I've just subscribed and I want to ask about the difference between the EShop and Gatherly projects, which one is better to learn from?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      They're slightly different, cant' say one is better than the other

  • @wdorsett84
    @wdorsett84 Год назад +2

    Great video! Thank you! Just to confirm when using named clients, the concern over transient vs singleton lifestyles isn't a concern? It's just with typed clients?

    • @Sanabalis
      @Sanabalis Год назад

      Correct. Since you use a factory to create the named client inside the method each time you invoke it, the lifetime of the class instance is not a factor at all. This is true only if the named client is created inside the method.
      However, should you create (and capture) named clients inside the constructors, you will effectively introduce the same issues as when using the typed client. Capture the factory instead.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Yes, since with named clients you create an instance and dispose of it. If you capture the client in a field, you have a similar issue

  • @vishalsaini-py4yd
    @vishalsaini-py4yd Год назад +1

    Great video....can you please tell how I can configure multiple http client having different token mechanism and adding different authorisation header in each separate request.

  • @niezebenmansour3736
    @niezebenmansour3736 Год назад +2

    Thank you for the effort in this video!

  • @VijayKumar-wy9ku
    @VijayKumar-wy9ku Год назад +1

    If I'm using 10 different named clients, then 10 object of HttpClient is created using IHttpClientFactory. How can we configure a single instance of HttpClient throughout whole application?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Well if you want to 10 _DIFFERENT_ named clients, you have no other choice

  • @csegyud
    @csegyud Год назад +1

    It was a nicely built overview. Thank you!

  • @pigrebanto
    @pigrebanto 9 месяцев назад +1

    ok but what if the token expires and you need to renew it / pass-in it again? to me it seems that with Factory approach you configure it statically at application startup phase.

  • @DrHeinzDoofenshmirtz
    @DrHeinzDoofenshmirtz Год назад +1

    Is the last solution for types clients with the lifetime settings a valid and good approach to use? or is it more on the hacky side? I have never stumpled upon it, and I knew almost everything else in the video. Though it was much more well explained than I have read.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      MSFT recommendation: learn.microsoft.com/en-us/dotnet/fundamentals/networking/http/httpclient-guidelines

  • @ArnonDanon
    @ArnonDanon Год назад +2

    Great content as always Milan...thank you🤴🏻

  • @pmsivakumar
    @pmsivakumar Год назад +1

    How do you do when you need to fetch the access token dynamically and refresh when it expires with this approach?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      Check this out: ruclips.net/video/_u6v4D6qgDI/видео.html
      You need a DelegatingHandler on top of the HttpClient

  • @bahmansani3408
    @bahmansani3408 Год назад +1

    why can not find video about creating read models eventualy with eventual consistency?

  • @codingbloke
    @codingbloke Год назад +1

    Typed clients has too many gotcha's. In addition to the messy stuff you added at the end, what if you have multiple services that require the same HttpClient configuration? I just used named configurations and only inject the factory, simples.

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      You'd configure the services separately

    • @codingbloke
      @codingbloke Год назад

      @@MilanJovanovicTech Indeed but then what you would have is all that malarkey to provide a specific configuration of a HttpClient which is only ever used by a single type and that type's only job is to wrap a specific configuration of HttpClient.
      In that case again you might as well have that service type do all that work. It would take the factory and what other config services it needed, and have a private method that returns a configured HttpClient

  • @nanvlad
    @nanvlad Год назад +2

    What if I just call AddHttpClient() and inject HttpClient into services contstructors? Do they share the same instance or every service gets its own copy?

    • @TheMichaelos
      @TheMichaelos Год назад

      I wanted to ask the same question! @MilanJovanovicTech I would really appreciate if you could elaborate on differences between factory injection and direct client injection 🙏

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      In theory, it shouldn't work - because no HttpClient would be wired up for that service

  • @grm360
    @grm360 Год назад +1

    Nice content as always! Could you make a video on how to use Swagger documentation with minimal api?

  • @coder3123
    @coder3123 9 месяцев назад +1

    If I were to call API2 from my API1 and the API2 accepts the bearer token that API1 call has is there a way to pass that as header using this method?

    • @MilanJovanovicTech
      @MilanJovanovicTech  9 месяцев назад

      You can either create a request object, and set the header. Or set the DefaultRequestHeaders on the HttpClient

  • @Ram92026z
    @Ram92026z Год назад +1

    Hi @Milan. This was an absolute great video and I am learning a ton from this channel and so, thank you. Hey, how can I use the above method (the 3rd way you describe in the above video) if I am working off of a class library project and I need to use httpClient within it. Basically, all my API calls are in a class library project. Is there an optimal way of using httpClient in it because I am worried about port exhaustion? Thanks

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      If you can create one HttpClient, pass it a SocketsHttpHandler instance at creation with some connection lifetime, and store it in a static field so that it's long-lived - that should suffice

    • @ramprahalad5579
      @ramprahalad5579 Год назад

      @@MilanJovanovicTech , got it! It is that oldish pattern of using the HttpClient I guess. Thanks a lot!

  • @pitthp
    @pitthp 9 месяцев назад +1

    What is good configuration for PooledConnectionLifeTime for Integration test project,
    that have a hundred test with API calls?

    • @MilanJovanovicTech
      @MilanJovanovicTech  9 месяцев назад

      How long does it take for your test suite execute?

  • @juke-duke
    @juke-duke Год назад +1

    What if you make the typed client a static class with a static HttpClient?

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад

      That works cool, since clients should be long-lived (at least the underlying message handler)

  • @DavideSansoni
    @DavideSansoni 4 месяца назад

    Great Video!! Just a curiosity: what VS theme are you using? Looks very clean

  • @floralb5317
    @floralb5317 Год назад +1

    Hello Milan,
    Thank you for amazing content. Something is bothering me regarding the configurations you need for a HttpClient. Let's say that you have some configuration stored in Azure Key Vault/Azure SQL Database, and each incoming request to our API has some kind of x-clientId header, how would you handle creating named HttpClient or strong typing HttpClient after retrieving some metadata on Azure Key Vault/Azure SQL?
    Thank you, keep up the good work :)

    • @MilanJovanovicTech
      @MilanJovanovicTech  Год назад +1

      I would explore an option of using a DelegatingHandler, to access Key Vault or SQL and get the configuration value.

  • @vibes992000
    @vibes992000 Год назад +1

    Must awaited video. Thanks.

  • @kodindoyannick5328
    @kodindoyannick5328 9 месяцев назад +1

    Very good content! Thanks Milan.

  • @lucid111lucid
    @lucid111lucid 10 месяцев назад

    My use case is a DLL which will be used with a winforms program. I expect that my DLL will be called periodically (hourly) and occasionally for a short burst of http activity. What video do you have that might help me choose the best implementation method? /Rob

    • @MilanJovanovicTech
      @MilanJovanovicTech  10 месяцев назад

      "short burst of http activity" - it doesn't look like you can do much harm whichever implementation you opt for. You could create a static HttpClient in the DLL and reuse it.

  • @norbertcsibi7720
    @norbertcsibi7720 2 месяца назад

    Based on that service, how do you write tests now to test that the httpclient got called once with x url?

    • @MilanJovanovicTech
      @MilanJovanovicTech  2 месяца назад

      Functional testing. Or you can mock the message handler with something like this: github.com/richardszalay/mockhttp

  • @user-tk2jy8xr8b
    @user-tk2jy8xr8b Год назад +1

    It's a pity that AddHttpClient forces you to use service locator pattern

  • @mentalmadness9783
    @mentalmadness9783 2 дня назад

    isn't it better if the typed client actually still has the name client in itself so it's easier to understand for other developers?

  • @astroGTC
    @astroGTC Год назад +1

    Great !! keep the good work !

  • @adriancamposteixeira5483
    @adriancamposteixeira5483 Год назад +1

    why not the "using" or "dispose"?

  • @sanilkumarn.s8974
    @sanilkumarn.s8974 3 месяца назад

    Hello, Is it possible to inject httpclient in .net framework 4.8?

    • @MilanJovanovicTech
      @MilanJovanovicTech  3 месяца назад

      Yes, I believe it's available in .NET Framework (and recommended)

  • @AyoJAjayi
    @AyoJAjayi 3 месяца назад

    Thanks for this lesson

  • @MahmoudSaed98
    @MahmoudSaed98 3 месяца назад

    why didn't you use Try - Catch to Handle Exceptions that may occur

  • @zfold4702
    @zfold4702 Год назад +2

    Now extend this for clients that need to send Jwt Token in headers with refresh token capability

  • @faisal3374
    @faisal3374 25 дней назад

    Should I dispose the HttpResponseMessage?

  • @AmirHashemZadeh
    @AmirHashemZadeh Год назад +1

    well done

  • @EvgeniyYatsenko
    @EvgeniyYatsenko 3 месяца назад

    great stuff!

  • @elfatel
    @elfatel Год назад +1

    Thanks

  • @Alaa_vie
    @Alaa_vie 4 месяца назад

    Whats the difference between HttpClient and WebClient?

    • @MilanJovanovicTech
      @MilanJovanovicTech  4 месяца назад +1

      WebClient is obsolete and shouldn't be used: learn.microsoft.com/en-us/dotnet/api/system.net.webclient?view=net-8.0

    • @Alaa_vie
      @Alaa_vie 3 месяца назад

      @@MilanJovanovicTech thank you

  • @chairmakerPete
    @chairmakerPete 3 месяца назад

    I'm sticking to Blazor Server 😂

  • @thecodeman_
    @thecodeman_ Год назад +14

    Admit that you saw my post a few minutes ago, and in 20 minutes you recorded a 12-minute video, edited and uploaded it. Just admit it, I'll forgive you..

  • @PauloMorgado
    @PauloMorgado Год назад

    You forgot to dispose the clients.

  • @kimpedersen4746
    @kimpedersen4746 Месяц назад

    thx alot , consise and informative