I have a REST library. These are the abstractions. Have I missed anything that a developer would need to use this in a dependency injection / IoC Container scenario? Anything that bothers you about this?
public interface IRestClient
{
IRestHeadersCollection DefaultRequestHeaders { get; }
TimeSpan Timeout { get; set; }
Task DeleteAsync(Uri queryString);
Task DeleteAsync(Uri queryString, CancellationToken cancellationToken);
Task<RestResponse<TReturn>> GetAsync<TReturn>();
Task<RestResponse<TReturn>> GetAsync<TReturn>(Uri queryString);
Task<RestResponse<TReturn>> GetAsync<TReturn>(Uri queryString, CancellationToken cancellationToken);
Task<RestResponse<TReturn>> PatchAsync<TReturn, TBody>(TBody body, Uri queryString);
Task<RestResponse<TReturn>> PatchAsync<TReturn, TBody>(TBody body, Uri queryString, CancellationToken cancellationToken);
Task<RestResponse<TReturn>> PostAsync<TReturn, TBody>(TBody body, Uri queryString);
Task<RestResponse<TReturn>> PostAsync<TReturn, TBody>(TBody body, Uri queryString, CancellationToken cancellationToken);
Task<RestResponse<TReturn>> PutAsync<TReturn, TBody>(TBody body, Uri queryString);
Task<RestResponse<TReturn>> PutAsync<TReturn, TBody>(TBody body, Uri queryString, CancellationToken cancellationToken);
}
public interface IRestClientFactory
{
IRestClient CreateRestClient(Uri baseUri);
IRestClient CreateRestClient();
}
public interface IRestHeadersCollection : IEnumerable<KeyValuePair<string, IEnumerable<string>>>
{
void Add(string name, string value);
void Add(string name, IEnumerable<string> values);
void Clear();
IEnumerable<string> this[string name]
{
get;
}
bool Contains(string name);
}
public partial interface ISerializationAdapter
{
/// <summary>
/// Takes an object of Type T and converts it to binary data
/// </summary>
Task<byte[]> SerializeAsync<T>(T value);
/// <summary>
/// Takes binary data and converts it to an object of type T
/// </summary>
Task<T> DeserializeAsync<T>(byte[] data);
}
public interface ITracer
{
void Trace(HttpVerb httpVerb, Uri baseUri, Uri queryString, byte[] body, TraceType traceType, int? httpStatusCode, IRestHeadersCollection restHeadersCollection);
}
public class RestResponse<TBody> : RestResponse
{
public TBody Body { get; }
public RestResponse(TBody body, IRestHeadersCollection restHeadersCollection, int statusCode, object underlyingResponse) : base(restHeadersCollection, statusCode, underlyingResponse)
{
Body = body;
}
#region Implicit Operator
public static implicit operator TBody(RestResponse<TBody> readResult)
{
return readResult.Body;
}
public TBody ToTBody()
{
return Body;
}
#endregion
}
public class RestResponse
{
#region Public Properties
public int StatusCode { get; }
public object UnderlyingResponse { get; }
public IRestHeadersCollection Headers { get; }
#endregion
#region Constructor
public RestResponse(IRestHeadersCollection restHeadersCollection, int statusCode, object underlyingResponse)
{
StatusCode = statusCode;
UnderlyingResponse = underlyingResponse;
Headers = restHeadersCollection;
}
#endregion
}
Originally I thought it might be useful to allow task async calls for serialization/deserialization but I've come to think that this is a bit redundant... Any thoughts on this?
System.Net
forHttpStatusCode
, why not useHttpMethod
instead of customHttpVerb
enum? If truly trying to abstract away then why notint?
for status code? \$\endgroup\$HttpClient
if one is not provided. This can lead to socket exhaustion. \$\endgroup\$