Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make multiple rest api calls and combine the result using c# [closed]

Here is the scenario where I need help.

  • User enters keyword and hit search

  • I am providing that keyword to multiple APIs in order to get the results using httpclient request.

  • I am getting response based on search keyword from different APIs.

But the issue is I am making search calls one by one to these apis. I want to do something where once user hits search it makes call to all the APIs at once and then combine the results.

WalmartModel model=new WalmartModel();

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("**URL 1**");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    //GET Method  
    HttpResponseMessage response = await client.GetAsync("");
    if (response.IsSuccessStatusCode)
    {
        model = await response.Content.ReadAsAsync<WalmartModel>();
    }
    else
    {
        Console.WriteLine("Internal server Error");
    }                
}


using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("**URL 2**");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    //GET Method  
    HttpResponseMessage response = await client.GetAsync("");
    if (response.IsSuccessStatusCode)
    {
        model = await response.Content.ReadAsAsync<WalmartModel>();
    }
    else
    {
        Console.WriteLine("Internal server Error");
    }                
}

once I get the result I am combining the list and returning it.(which I don't think is a best practice to follow.)

I know I can utilize multitasking threads but i have no practical examples to follow. Can anyone suggest the best approach to handle this ?

like image 694
Sachin Trivedi Avatar asked Feb 05 '23 04:02

Sachin Trivedi


1 Answers

Here is an approach you can take.

Encapsulate the calls to the different APIs into async functions that return a common model. In this case a common method that will return WalmartModel after querying a URL.

public async Task<WalmartModel> GetModel(string url, HttpClient client) {
    //GET Method  
    using(var response = await client.GetAsync(url)) {
        if (response.IsSuccessStatusCode) {
            return await response.Content.ReadAsAsync<WalmartModel>();
        } else {
            Console.WriteLine("Internal server Error");
        }
    }         
    return null;       
}

Use Task.WhenAll to await all the API searches and collect the results when they complete

//Using a single client to make the calls.
using(var client = new HttpClient()) {
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    //create the search tasks to be executed
    var tasks = new []{
        GetModel("**URL 1**", client),
        GetModel("**URL 2**", client),
        GetModel("**URL N**", client),
    };

    // Await the completion of all the running tasks. 
    var responses = await Task.WhenAll(tasks); // returns IEmumerable<WalmartModel>

    var results = responses.Where(r => r != null); //filter out any null values
}

Task.WhenAll returns a single task that finishes when all the tasks in the collection of tasks have completed.

like image 188
Nkosi Avatar answered Feb 07 '23 18:02

Nkosi