I am writing a class that is sending quite a few GET requests and I am looking for the right way to consolidate them. I have extracted the common logic into a method called GetRequest. Here is what it looks like at the moment:
private async Task<HttpResponseMessage> GetRequest(string message)
{
_uriBuilder.Path = _commonApiPath + message;
return await _client.GetAsync(_uriBuilder.Uri.AbsoluteUri);
}
public async Task<HttpResponseMessage> GetA()
{
return await GetRequest("sys/a");
}
public async Task<HttpResponseMessage> GetB()
{
return await GetRequest("sys/b");
}
public async Task<HttpResponseMessage> GetC()
{
return await GetRequest("sys/c");
}
public async Task<HttpResponseMessage> GetX()
{
return await GetRequest("sys/x");
}
public async Task<HttpResponseMessage> GetY()
{
return await GetRequest("sys/y");
}
This approach is straightforward and it works, but is there some language feature that I am able to use in order to combine those calls? The only real difference is the string that is passed as the message. I don't want the consumer of this class to have to include the message string since it could be potentially written incorrectly.
I was considering trying to use Func<>/Action<> or lambdas to consolidate, but each one seems to have a limitation which makes me think it's not the correct approach.
If this is just to constrain the allowed values, expose an enum to the callers, then use a dictionary behind the scenes:
public enum RequestType {
A,
B,
...
}
private static readonly Dictionary<RequestType, string> RequestPaths = new Dictionary<RequestType, string> {
{ RequestType.A, "sys/a"},
{ RequestType.B, "sys/b"}
};
public async Task<HttpResponseMessage> GetRequest(RequestType request)
{
_uriBuilder.Path = _commonApiPath + RequestPaths[request];
return await _client.GetAsync(_uriBuilder.Uri.AbsoluteUri);
}
This will throw at runtime if they cast an unknown value to RequestType
but it usually suffices in keeping the honest callers honest.