HttpClient To Get List With Async/Await Operation
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Fetching a list from an HTTP API in C# is a normal HttpClient plus JSON-deserialization workflow. The async part is not optional decoration. It is the correct way to avoid blocking a thread while the network request is in flight. The reliable pattern is to make the request with await, validate the response, then deserialize the JSON into List<T> or another collection type.
Define a Model That Matches the JSON
Suppose the API returns JSON like this:
A matching C# model might be:
The property names should line up with the JSON payload, or you should configure the serializer accordingly.
Use GetFromJsonAsync for the Simple Case
In modern .NET, the easiest option is GetFromJsonAsync.
This is a good default when the endpoint returns JSON directly and you do not need special response inspection first.
Use GetAsync When You Need More Control
If you need to inspect status codes, headers, or errors before deserializing, use GetAsync and then read the content explicitly.
This form is more verbose, but it is better when you care about failure handling or non-JSON edge cases.
Reuse HttpClient
One of the most important practical rules is to reuse HttpClient instead of creating a new instance per request.
Bad pattern:
This looks harmless, but frequent short-lived HttpClient instances can contribute to socket exhaustion and unnecessary connection churn. Prefer a shared instance, dependency injection, or IHttpClientFactory in larger applications.
Handle Exceptions Deliberately
Real HTTP calls fail. Network outages, timeouts, invalid JSON, and non-success status codes all need deliberate handling.
The exact exception strategy depends on your app, but pretending the request always succeeds is not acceptable production code.
Return the Right Collection Type
If the API returns an array, List<T> is usually fine. If it returns a wrapper object such as:
then your model must match that shape.
Do not deserialize straight into List<T> unless the JSON root actually is a JSON array.
Common Pitfalls
A common mistake is calling .Result or .Wait() instead of using await. That blocks the current thread and defeats the point of asynchronous I/O.
Another issue is creating a new HttpClient per request. Reuse matters for performance and connection management.
Developers also often deserialize into the wrong shape. If the JSON root is an object, List<T> is not the right target type.
Finally, do not skip response validation. If you do not inspect or enforce success status codes, deserialization errors can hide the real HTTP failure.
Summary
- Use
awaitwithHttpClientto fetch lists without blocking threads. - '
GetFromJsonAsync<List<T>>is the simplest path when the endpoint returns a JSON array.' - Use
GetAsyncplusReadFromJsonAsyncwhen you need more response control. - Reuse
HttpClientinstead of creating one per request. - Make sure the C# model matches the actual JSON shape returned by the API.

