A resource-oriented HTTP client for .net
via NuGet:
PM> Install-Package Everest
var client = new Everest.RestClient();
// GET http://www.google.com
var homePage = client.Get("http://www.google.com");
// GET http://www.google.com/search?q=everest+http+client
var searchResults = homePage.Get("search?q=everest+http+client");
...
To use Everest, create a RestClient:
var client = new Everest.RestClient();
A RestClient is a Resource, therefore it can be used to make requests, such as "Get" requests:
var homePage = client.Get("http://www.google.com");
The response (homePage) is a Response, which itself is also a Resource, so we can call "Get" on that too, to get a new Response, relative to the URI that responded to the first request:
// GET http://www.google.com/search?q=everest+http+client
var searchResults = homePage.Get("search?q=everest+http+client");
All requests return Responses, so we can do this over and over.
Everest requests are ultimately dispatched by calling the "Send" method on a Resource, to get a Response:
namespace Everest
{
public interface Resource
{
...
Response Send(HttpMethod method, string uri, BodyContent body, params PipelineOption[] overridingPipelineOptions);
...
}
}
Most of the time, you have a particular verb in mind when you make an HTTP request, so you'll want the convenient Resource API extension methods:
namespace Everest
{
public static class ResourceApi
{
...
public static Response Get(this Resource resource, string uri, params PipelineOption[] pipelineOptions)
{
return resource.Send(HttpMethod.Get, uri, null, pipelineOptions);
}
...
}
}
When you make HTTP requests, you often need to set specific parameters (such as request headers), or handle responses in a particular way. For anything beyond the request URI and body, Everest allows the request and/or response handling to be tweaked, using pipeline options:
using Everest;
using Everest.Headers;
...
var client = new RestClient(new RequestHeader("X-Requested-With", "Everest"));
RequestHeader is one example of a PipelineOption, which are used to customise the way Everest handles requests and responses.
PipelineOption is a marker interface implemented by anything that can customise a request or its response handling.
Pipeline options can be applied to all requests by passing them to the RestClient constructor:
var options = new PipelineOption[] { ExpectStatus.OK, new RequestHeader("foo", "bar") }
new RestClient(options);
...or applied to a single request at a time (often overriding existing options):
new RestClient().Get(url, new RequestHeader("foo", "baz"))
The following pipeline options can be used to customise request/response behaviour:
-
BasicAuth sets the 'Authorization' header for HTTP Basic authentication
-
IfModifiedSince sets the 'If-Modified-Since' HTTP header
-
SetRequestHeaders sets arbitrary HTTP request headers.
-
ExpectResponseHeaders throws exceptions when unexpected header values are present.
-
ExpectStatus throws exceptions when the response status code is unexpected.
-
ExpectStatusInRange throws exceptions when the response status code is outside a range of values.
-
ExpectStatusNotInRange throws exceptions when the response status code is inside a range of values.
An implementation of BodyContent can be passed into any request that takes a payload (e.g. POST/PUT):
namespace Everest.Content
{
public interface BodyContent
{
Stream AsStream();
string MediaType { get; }
}
}
A couple of implementations of BodyContent should come in handy:
-
Use StringBodyContent to send plain old text/plain
-
StreamBodyContent for stuff that can be streamed
-
JsonBodyContent for a JSON request body
By default, Everest throws an exception if the response status code is in the range 400-599.
You can override the acceptable response status code:
// Create a client that doesn't usually complain about errors
client = new RestClient(ExpectStatus.IgnoreStatus)
// GET request, expecting a 404
client.Get("foo", ExpectStatus.NotFound)
// POST request, expecting a 201
client.Post("foo", "body", new ExpectStatus(HttpStatusCode.Created))
By default, Everest will automatically follow redirects. Change that behaviour with the AutoRedirect option:
client.Post("/foos", "body", AutoRedirect.DoNotAutoRedirect)
For security, Authorization headers are not sent in requests following automatic redirects. This can be overridden:
client.Put("/foos/1", "body", AutoRedirect.AutoRedirectAndForwardAuthorizationHeader)
Given a resource, Resource.With(params PipelineOption[] options) returns a new client with overridden default options:
var client = new RestClient("http://www.example.com");
var authenticatedAjaxClient = client.With(new BasicAuth("user", "pass"))
.With(new RequestHeader("X-Requested-With", "ajax"));
I know, sorry. I work with a guy called Julian Everett, who is an expert in the art of REST. This project is named (nearly) after him.