Client Overview
Grapevine.Client exposes a set of extensions methods to make sending REST requests with HttpClient both readable and chainable.
Correctly Injecting HttpClient#
The socket exhaustion problems assocaited with the incorrect usage of the HttpClient class in .NET applications has been well documented. Microsoft has published an article introducing IHttpClientFactory, which is used to configure and create HttpClient instances in an app. When using the extensions in Grapevine.Client, it is recommended that these patterns are followed.
Brief Sample#
This brief sample creates a client for GitHub. In your applications Startup class, use the built in extension class AddHttpClient.
This will both register our GitHubClient class with the service collection, and registers a named client and a configuration to be used with that client. When the client is eventually injected into the class below, it will already have the base address assigned, and the default headers needed to make requests to the GitHub api added and defined.
References#
- You're Using HttpClient Wrong And It Is Destabilizing Your Software
- Make HTTP requests using IHttpClientFactory in ASP.NET Core
- Use IHttpClientFactory to implement resilient HTTP requests
Extension Methods#
Using HttpClient involves creating an HttpRequestMessage, configuring it's properties (e.g. headers, query string, route, etc.), serializing the content, and sending that request. The response then needs to be deserialized and used.
The extension methods available in this library simplifiy that process. The UsingRoute extension method on HttpClient returns a RestRequestBuilder object, which has extension methods on it to configure the request. It also has extension methods to send the request using different HTTP verbs, and then there are extension methods on both HttpResponseMessage and Task<HttpResponseMessage>for deserializing the content. Put another way, the extension methods fall in to three categories.
- Configuring the
HttpRequestMessage - Sending the
HttpRequestMessage - Deserializing the
HttpResponseMessagecontents
The example below proceed in that order, based on topic, or you can jump to a specific method:
UsingRoute(string route)
To enjoy the benefits of using these chaning methods, you'll need to configure the request and send it all in one chain.
Configure The Request#
Route (Endpoint)#
Start by setting the request route using the UsingRoute(string route) extension method. If the HttpClient.BaseAddress has already been set, the value should be relative to that value. If it has not, then you should include the fully qualified domain name and full path the endpoint.
You'll notice that this is the only extension method on HttpClient of those listed here. This method actually returns a RestRequestMessageBuilder, and all other methods below are extension methods on that class.
Authentication#
If your requests need authentication, you can easily add it using one of the three extensions methods below.
Basic Authentication#
Basic authentication sends a Base64 encoded username and password. You can create the Base64 encoded string yourself or let the extension method do that for you.
OAuth Authentication#
Other Authentication Schemes#
Or you can use a different authentication scheme by passing in the type and credentials.
Content#
You can set the content of the request by passing in a string or a pre-built HttpContent object.
Cookies#
You can set one or many cookies on the request.
Headers#
You can set one or many headers on the request.
caution
It is not recommended to use this method to set cookies or authentication headers, as other extension methods may override those headers.
Query Parameters#
Add query parameters to the route.
Timeout#
You can set the timeout value for a request by passing either a number of seconds as an integer or passing in a TimeSpan instance.
Send The Request#
There are extension methods specifically for the most common HTTP methods, or you can pass in the method to be used. All of the methods take an optional cancellation token (not shown).
Deserialize The Response#
You can deserialize the response body to a string, stream or byte array using an extension method on the response.