Reputation: 30298
In my MVC app, I make a lot of Web API calls that require a few lines of code. I'd like to create a centralized method for making API calls and just pass some simple parameters into it e.g. call type (GET, POST, etc), the Url, etc.
Where I need help is that in each scenario, I will return a different object type e.g. Employee, List<Project>, etc. How do I return different object types?
The other issue is that if I want to make a POST or PUT call, I will pass different types of objects into my centralized API call method. Again, I have the same issue, where I have to be able to accept different object types.
I guess, I can just pass Json objects in and out but I'm not sure if that's the right approach or there's a better approach out there. I'm sure others have tried to centralize their Web API call code.
* UPDATE * Here's what I have so far but I need a bit more help. How do I return the result?
public static async Task<object> GetApiCall(string apiActionUrl)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://myApiBaseUrl");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(apiActionUrl);
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadAsStringAsync().Result;
}
}
}
Upvotes: 2
Views: 1079
Reputation: 4130
Try this : this is a starting point, you can build on this, but the idea is ApiCaller is a class that implements an interface IApiCaller (so you can mock it later), and this class starts the HttpClient with the same options/headers, and the method will use/dispose this HttpClient to connect to the server, and each method defines the return type T when the caller calls the method (like Get).
public interface IApiCaller
{
Task<T> Get<T>(string apiActionUrl);
}
public class ApiCaller : IApiCaller
{
private const string ApiBaseUrl = "http://myApiBaseUrl";
public async Task<T> Get<T>(string apiActionUrl)
{
using (var client = GetHttpClient())
{
var response = await client.GetAsync(apiActionUrl);
if (response.IsSuccessStatusCode)
{
var jsonString = response.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<T>(jsonString);
}
}
return default(T);
}
private static HttpClient GetHttpClient()
{
var client = new HttpClient
{
BaseAddress = new Uri(ApiBaseUrl),
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return client;
}
}
you can use this class like this:
public class SomeMvcController : Controller
{
private readonly IApiCaller _apiCaller;
// use this if you don't want to rely on Dependency Injection, OR
// if you don't use Ioc container for now.
public SomeClass(): this(new ApiCaller())
{
}
public SomeClass(IApiCaller apiCaller)
{
_apiCaller = apiCaller;
}
public async Task<string> GetStringFromWebApi()
{
string result = await _apiCaller.Get<string>("myApiUrl");
return result;
}
}
Hope that helps.
Upvotes: 1