1

This is something that could be really noob, but I really would like to understand. I´m doing a console application that makes a request to Swapi API (the star wars api) and, catch all the starships available on the API. When I hit their API (https://swapi.co/api/starships), the response return a field called "next", that has the other part of the starships that they have (the API is making the pagination on each request)

Well, I´ve made a class that do the first request to their API, deserialize the object, and inside of a while, I verify if the field "next" is null and do the rest of the requests with the field "next"

This is my code

public class RequestToSwapiApi : IRequestToSwapiApi
    {
        private string Json;

        private string ApiURL
        {
            get
            {
                return "https://swapi.co/api/starships/";
            }
        }

        public async Task<RootObject> ReturnTheStarShipModels()
        {
            var request = new HttpClient();
            this.Json = await request.GetStringAsync(this.ApiURL);
            var rootObject = JsonConvert.DeserializeObject<RootObject>(this.Json);

            while (rootObject.Next != null)
            {
                this.Json = await request.GetStringAsync(rootObject.Next);
                var newDeserializeObject = JsonConvert.DeserializeObject<RootObject>(this.Json);
                if (newDeserializeObject.Results != null)
                {
                    rootObject.Results.AddRange(newDeserializeObject.Results);
                }

                rootObject.Next = newDeserializeObject.Next;
            }

            return rootObject;
        }
    }

I know that if I use a block of code "using HttpClient", I will avoid the necessity of using the disposable. But, If I use that block code "using HttpClient" inside of a loop the way I´m doing above, the object that I´m creating will be reusable? Or it will be created, and disposable foreach time that the loop occours? The way I´m doing it could cause performance issues?

  • 5
    Ah, HttpClient. Though it's disposable, you really shouldn't be disposing it. Take a look at https://stackoverflow.com/questions/15705092/do-httpclient-and-httpclienthandler-have-to-be-disposed and other similar information on the web – Flydog57 Jan 18 '20 at 01:23
  • Thanks for the response. I´m asking that, because I was reading this article https://johnthiriet.com/efficient-api-calls/, and I got confused because on every example he´s using this (var client = new HttpClient()). So I didn´t get it the idea behind that – Heitor Ribeiro Jan 18 '20 at 01:36
  • 1
    The problem is that experienced C# programmers see a class that implements `IDisposable` and know that they need to wrap instances in `using`. I don't know why HttpClient breaks this rule. I suspect that the design expectation was that it would be used like a SqlConnection instance, but after the interface was published, they realized that it worked better it it was managed more like a singleton – Flydog57 Jan 18 '20 at 02:42
  • @Flydog57 well, yes, `IDisposable` have to be disposed, but question is when. For Web API, that is using `HttpClient` in the controller methods, `HttpClient` should be disponsed only before service shut down. – Alexander Goldabin Jan 18 '20 at 11:35
  • 1
    @HeitorRibeiro for Net.Core 2.1 and above you could use `IHttpClientFactory` to deal with HttpClients. Please, see this article for more details: https://www.stevejgordon.co.uk/introduction-to-httpclientfactory-aspnetcore – Alexander Goldabin Jan 18 '20 at 11:36
  • @alexandergoldabin: thanks! That's a very interesting read. Time to update our dev standards yet again – Flydog57 Jan 18 '20 at 20:30
  • @AlexanderGoldabin thanks for the article. I didn´t know about the new interface available, and why we should use that. It´s really good to update our standards – Heitor Ribeiro Jan 18 '20 at 21:36
  • @AlexanderGoldabin The article that you passed really helped me on my question about the disposable. Thanks a lot for that. If you want, post as the answer of this question, and I will mark as the right one. Sorry for the late response – Heitor Ribeiro Jan 22 '20 at 14:55

1 Answers1

1

Answering particular question: you don't need to dispose your HttpClient, neither in while loop, nor in the whole request method. Since your application performing requests to external API using HttpClient, then HttpClient need to be disposed only when your application shuts down.

For NET Core 2.1 and above there's a useful abstraction called HttpClientFactory that creates and manages pool of HttpClients for you. You need just to register it in DI Container:

public void ConfigureServices(IServiceCollection services)
{
    // Registering IHttpClientFactory
    services.AddHttpClient();
    // ...
}

...and inject in your class:

public class RequestToSwapiApi
{
    private readonly IHttpClientFactory _clientFactory;

    public RequestToSwapiApi(IHttpClientFactory httpClientFactory)
    {
        _clientFactory = clientFactory;
    }

    public async Task<RootObject> ReturnTheStarShipModels()
    {
        HttpClient client = _clientFactory.CreateClient();
        //...

For more information:

Alexander Goldabin
  • 1,824
  • 15
  • 17