C# REST / Http Client Abstraction
IRestClient looks over-engineered. All of those helper members merge down to one common Call which can make the interface much simpler to define.

public interface IRestClient {
    IRestHeadersCollection DefaultRequestHeaders { get; }
    string DefaultContentType { get; set; }
    TimeSpan Timeout { get; set; }
    Task&lt;RestResponse&lt;TReturn&gt;&gt; SendAsync&lt;TReturn&gt;(RestRequest request, CancellationToken cancellationToken = default(CancellationToken));
}


The client now simplified to its core features.

The commonly used parameters can be aggregated into a class

public class RestRequest {

    public RestRequest() {
    }

    public RestRequest(IRestClient client) : this() {
        var contentType = client.DefaultContentType;
        if (!string.IsNullOrEmpty(contentType)) {
            ContentType = contentType;
        }
        var headers = client.DefaultRequestHeaders;
        if (headers != null) {
            foreach (var header in headers) {
                Headers.Add(header.Key, header.Value);
            }
        }
    }

    public IRestHeadersCollection Headers { get; } = new RestRequestHeaders();

    public Uri Resource { get; set; }
    public HttpVerb HttpVerb { get; set; } = HttpVerb.Get;
    public string ContentType { get; set; } = "application/json";
    public object Body { get; set; }

    class RestRequestHeaders : HttpHeaders, IRestHeadersCollection {
        public RestRequestHeaders() : base() { }
        public IEnumerable&lt;string&gt; this[string name] =&gt; GetValues(name) ?? Array.Empty&lt;string&gt;();
    }
}


Naming is important here. Change the name to resource from queryString, which means something different to how it was originally being used with regards to HTTP requests.

Parameter order should also be changed to be more consistent.

Your original call would have looked something like

...await client.PostAsync&lt;ReturnObject, BodyObject&gt;(body, "...");


with the URI parameter second. When making the request, the first argument should be the resource being called. Everything else can be built up from there

...await client.PostAsync&lt;ReturnObject, BodyObject&gt;("...", body);
...await client.PostAsync&lt;ReturnObject, BodyObject&gt;("...", body, token);
//...etc


The following extensions allow for the same functionality as before on the IRestClient abstraction

public static class RestClientExtensions {
    #region Delete
    public static Task DeleteAsync(this IRestClient client, string resource) {
        return client.DeleteAsync(new Uri(resource, UriKind.Relative));
    }

    public static Task DeleteAsync(this IRestClient client, Uri resource) {
        return client.DeleteAsync(resource, CancellationToken.None);
    }

    public static Task DeleteAsync(this IRestClient client, Uri resource, CancellationToken cancellationToken) {
        var request = new RestRequest(client) {
            Resource = resource,
            HttpVerb = HttpVerb.Delete
        };
        return client.SendAsync&lt;object&gt;(request, cancellationToken);
    }
    #endregion

    #region Get
    public static Task&lt;RestResponse&lt;TReturn&gt;&gt; GetAsync&lt;TReturn&gt;(this IRestClient client) {
        var request = new RestRequest(client) {
            HttpVerb = HttpVerb.Get
        };
        return client.SendAsync&lt;TReturn&gt;(request, CancellationToken.None);
    }

    public static Task&lt;RestResponse&lt;TResult&gt;&gt; GetAsync&lt;TResult&gt;(this IRestClient client, string resource) {
        try {
            return client.GetAsync&lt;TResult&gt;(new Uri(resource, UriKind.Relative));
        } catch (UriFormatException ufe) {
            if (ufe.Message == "A relative URI cannot be created because the 'uriString' parameter represents an absolute URI.") {
                throw new UriFormatException(Messages.ErrorMessageAbsoluteUriAsString, ufe);
            }
            throw;
        }
    }

    public static Task&lt;RestResponse&lt;TReturn&gt;&gt; GetAsync&lt;TReturn&gt;(this IRestClient client, Uri resource) {
        return client.GetAsync&lt;TReturn&gt;(resource, CancellationToken.None);
    }

    public static Task&lt;RestResponse&lt;TReturn&gt;&gt; GetAsync&lt;TReturn&gt;(this IRestClient client, Uri resource, CancellationToken cancellationToken) {
        var request = new RestRequest(client) {
            Resource = resource
        };
        return client.SendAsync&lt;TReturn&gt;(request, cancellationToken);
    }
    #endregion

    #region Patch
    public static Task&lt;RestResponse&lt;TReturn&gt;&gt; PatchAsync&lt;TReturn, TBody&gt;(this IRestClient client, Uri resource, TBody body) {
        return client.PatchAsync&lt;TReturn, TBody&gt;(resource, body, CancellationToken.None);
    }

    public static Task&lt;RestResponse&lt;TReturn&gt;&gt; PatchAsync&lt;TReturn, TBody&gt;(this IRestClient client, Uri resource, TBody body, CancellationToken cancellationToken) {
        var request = new RestRequest(client) {
            Resource = resource,
            HttpVerb = HttpVerb.Patch,
            Body = body,
        };
        return client.SendAsync&lt;TReturn&gt;(request, cancellationToken);
    }
    #endregion

    #region Post
    public static Task&lt;RestResponse&lt;TReturn&gt;&gt; PostAsync&lt;TReturn, TBody&gt;(this IRestClient client, TBody body, Uri querresourceString) {
        return client.PostAsync&lt;TReturn, TBody&gt;(body, querresourceString, CancellationToken.None);
    }

    public static Task&lt;RestResponse&lt;TReturn&gt;&gt; PostAsync&lt;TReturn, TBody&gt;(this IRestClient client, TBody body, Uri resource, CancellationToken cancellationToken) {
        var request = new RestRequest(client) {
            Resource = resource,
            HttpVerb = HttpVerb.Post,
            Body = body,
        };
        return client.SendAsync&lt;TReturn&gt;(request, cancellationToken);
    }
    #endregion

    #region Put
    public static Task&lt;RestResponse&lt;TReturn&gt;&gt; PutAsync&lt;TReturn, TBody&gt;(this IRestClient client, TBody body, Uri resource) {
        return client.PutAsync&lt;TReturn, TBody&gt;(body, resource, CancellationToken.None);
    }

    public static Task&lt;RestResponse&lt;TReturn&gt;&gt; PutAsync&lt;TReturn, TBody&gt;(this IRestClient client, TBody body, Uri resource, CancellationToken cancellationToken) {
        var request = new RestRequest(client) {
            Resource = resource,
            HttpVerb = HttpVerb.Put,
            Body = body,
        };
        return client.SendAsync&lt;TReturn&gt;(request, cancellationToken);
    }
    #endregion
}