Skip to content

Instantly share code, notes, and snippets.

@polterguy
Created May 10, 2019 12:59
Show Gist options
  • Save polterguy/b3853549ec6a472cddc58440635dd6b1 to your computer and use it in GitHub Desktop.
Save polterguy/b3853549ec6a472cddc58440635dd6b1 to your computer and use it in GitHub Desktop.
A C# class to easily invoke HTTP REST invocations with one line of code
/*
* Usage ...
* var foo = new SomeType { /*.Decorate instance here ... */ };
* var result = await Client.PostAsync<SomeType>("https://some-url.com/api", foo);
*/
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
namespace Magic.Http
{
public static class Client
{
public static async Task<Response> PostAsync<Response, Request>(
string url,
Request request,
Action<HttpClient> initializeFunction = null)
{
return await CreateRequest<Response>(initializeFunction, async (client) =>
{
using (var content = new StringContent(JObject.FromObject(request).ToString()))
{
return await client.PostAsync(url, content);
}
});
}
public static async Task<Response> PutAsync<Response, Request>(
string url,
Request request,
Action<HttpClient> initializeFunction = null)
{
return await CreateRequest<Response>(initializeFunction, async (client) =>
{
using (var content = new StringContent(JObject.FromObject(request).ToString()))
{
return await client.PutAsync(url, content);
}
});
}
public static async Task<Response> GetAsync<Response>(
string url,
Action<HttpClient> initializeFunction = null)
{
return await CreateRequest<Response>(initializeFunction, async (client) =>
{
return await client.GetAsync(url);
});
}
public static async Task<Response> DeleteAsync<Response>(
string url,
Action<HttpClient> initializeFunction = null)
{
return await CreateRequest<Response>(initializeFunction, async (client) =>
{
return await client.DeleteAsync(url);
});
}
static async Task<Response> CreateRequest<Response>(Action<HttpClient> decorator, Func<HttpClient, Task<HttpResponseMessage>> functor)
{
using (var client = new HttpClient())
{
decorator?.Invoke(client);
using (var response = await functor(client))
{
var responseContent = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(responseContent);
// In case caller wants to retrieve string, JObject, int, etc ...
if (typeof(IConvertible).IsAssignableFrom(typeof(Response)))
return (Response)Convert.ChangeType(responseContent, typeof(Response));
return JToken.Parse(responseContent).ToObject<Response>();
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment