locked
Reusable HttpClient RRS feed

  • Question

  • User1080340250 posted

    I'm just trying to figure out the cleanest, most efficient way to do recurring HttpClient requests with multiple endPoints.

    I'm trying to do this wthout something like Nuget so I have more transparency over what's happening.

    The below works, however I want to make it reusable with say List<Cities>, List<Cars>, etc...

    Also, I want to always pass certain Headers, say the current UserId from AspNetIdentity

            public static async Task<List<Category>> GetList()
            {
                var Categories = new List<Category>();
                string ActionPath = string.Format("{0}/v1/Categories", Connect.web);
                using (var response = await Client.GetAsync(ActionPath))
                {
                    string apiResponse = await response.Content.ReadAsStringAsync();
                    Categories  = JsonConvert.DeserializeObject<List<Category>>(apiResponse);
                }
                return Categories ;
            }

    I tried use a Base Class, but then I went around in circles trying to call HttpContext from static class, etc...I've looked for examples but there is so much noise online re: HttpClient or HttpClient Factory, I don't know where to start.

    What I was hoping to do was have just a few lines to indicate the specific endPoint, the returnType, etc...am I just living in a fantasy world?

    Saturday, November 21, 2020 3:07 PM

All replies

  • User475983607 posted

    Use DI to configure HttpClient.  If you have multiple services then create a factory.  These concepts are covered in official documentation.

    https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=net-5.0

    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0

    I tried use a Base Class, but then I went around in circles trying to call HttpContext from static class, etc...I've looked for examples but there is so much noise online re: HttpClient or HttpClient Factory, I don't know where to start.

    I feel a base class makes the DI code overly complex.  Use standard DI service patterns and C# generics.   Your service interface will have GET, POST, PUT, DELETE, etc. and perhaps a few method overloads loads.

    For example

    public interface IApiService
    {
        Task<T> GetAsync<T>(string accessToken, string restApi);
    }
    public async Task<T> GetAsync<T>(string accessToken, string restApi)
    {
        _logger.LogDebug($"Api = {restApi}");
    
        T results = (T)Activator.CreateInstance(typeof(T));
    
        var client = _httpClientFactory.CreateClient(_apiFactoryName);
        if (!string.IsNullOrEmpty(accessToken))
        {
            client.SetBearerToken(accessToken);
        }
               
        using (Stream s = await client.GetStreamAsync($"{restApi}"))
        {
            using (StreamReader sr = new StreamReader(s))
            {
                using (JsonReader reader = new JsonTextReader(sr))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    results = serializer.Deserialize<T>(reader);
                }
            }
        }
        return results;
    }

    Your POST implementation will also have input models.

    Saturday, November 21, 2020 3:41 PM