Search code examples
restblazor-server-sidedotnet-httpclient

Blazor Server App: More efficient API calls


I have built a Blazor Server App that relies on a lot of API requests. They are all identical with the exception of the URL and the object the result deserializes into. This has resulted in a great deal of duplicate code, but I don't know how to remove the duplication effectively. Here is an example of how I am making the call:

IEnumerable<MyObject> myObjectList = Array.Empty<MyObject>();

public async Task GetMyObjectList()
{
    string myUrl = "https://my.server.dns/myMethod";

    var myRequest = new HttpRequestMessage(HttpMethod.Get, myUrl);
    myRequest.Headers.Add("Accept", "application/vnd.github.v3+json");
    myRequest.Headers.Add("User-Agent", "HttpClientFactory-Sample");

    var myClient = ClientFactory.CreateClient();
    var myResponse = await myClient.SendAsync(myRequest);

    if (myResponse.IsSuccessStatusCode)
    {
        using var responseStream = await myResponse.Content.ReadAsStreamAsync();
        myObjectList = await JsonSerializer.DeserializeAsync<IEnumerable<MyObject>>(responseStream);
    }
}

I could construct the URL outside of the method and pass it in, but I can't figure out how to deserialize the response to the correct object. I tried just getting the JSON string back and using that, but I ended up with a string full of escaped quotes, that I couldn't deal with and it seemed a fairly lame way of dealing with the problem anyway.

I am not a developer, so please treat me gently!

Thanks in advance of any assistance offered.


Solution

  • You could use the Generic type T.

    public async Task<IEnumerable<T>> GetMyObjectList<T>(string url)
    {
        var myRequest = new HttpRequestMessage(HttpMethod.Get, url);
        myRequest.Headers.Add("Accept", "application/vnd.github.v3+json");
        myRequest.Headers.Add("User-Agent", "HttpClientFactory-Sample");
    
        var myClient = ClientFactory.CreateClient();
        var myResponse = await myClient.SendAsync(myRequest);
    
        if (myResponse.IsSuccessStatusCode)
        {
            using var responseStream = await myResponse.Content.ReadAsStreamAsync();
            return await JsonSerializer.DeserializeAsync<IEnumerable<T>>(responseStream);
        }
        else{
            return new List<T>();
        }
    }
    

    Call it like this:

    IEnumerable<MyObject> myObjectList = await GetMyObjectList<MyObject>("https://my.server.dns/myMethod");