As of late, much of the code I write, somehow or other has to communicate with an HTTP server. Be it a “ReSTful” service or a “Wanna-be-ReSTful” service, I’ve had the need to make GET, POST, PUT et al operations and work with JSON.
After writing smaller wrappers around WebRequest on a few occasions, I decided it’s time to formalize the wrapper. This has given way to EasyHttp. It’s been sitting on GitHub for quite some time and both myself and others have been using it for several projects, so I think it’s reached a point where more people can try it out if they wish.
Best way to describe the features of EasyHttp is with some code
{
Request = {Accept = HttpContentTypes.ApplicationJson}
};
var response = http.Get("http://domain.com/customer/25");
var customer = response.StaticBody<Customer>();
The code is self-describing: we create an instance of HttpClient and indicate that we accept content-type application/json (since in this case the server sends us json). By specifying this Accept header, EasyHttp knows how to decode the request.
How do we obtain the response? In the code above we are using the StaticBody method which gives us back a strongly-typed Customer. But we have other options:
{
Request = {Accept = HttpContentTypes.ApplicationJson}
};
var response = http.Get("http://domain.com/customer/25");
dynamic customer = response.DynamicBody();
Console.WriteLine(customer.Name);
Console.WriteLine(customer.Email);
In this case we want to return a dynamic type so we call the DynamicBody method. EasyHttp will automatically deserialize the response to a dynamic object. This allows us to access properties without having to declare types ahead of time (quite useful when working with JSON). Finally we can also get access to the raw response via the RawText property.
If we want to stream to a file, we simply do:
http.GetAsFile("http://hadihariri.com/header.png", @"C:\Temp\header.png");
Working with other verbs is pretty much the same process. Let’s say we want to create a customer calling a service:
var customer = new Customer()
{
Name = "Joe Smith",
Email = "Joe@Gmail.com"
};
http.Post("http://domain.com/customer", customer, HttpContentTypes.ApplicationJson);
In this case we are posting a Customer object and asking EasyHttp to encode it using application/json. Similar to when receiving a response, when making a request that requires a body, we can also use dynamic objects. As such, this would also work:
dynamic customer = new ExpandoObject();
customer.Name = "Joe Smith";
customer.Email = "Joe@Gmail.com";
http.Post("http://domain.com/customer", customer, HttpContentTypes.ApplicationJson);
Internally, EasyHttp is using the excellent JsonFX which currently provides support for JSON and XML encoding/decoding. EasyHttp extends this by adding encoding support for www-form-urlencoded. Extending it with other format should be pretty easy.
As well as GET and POST, EasyHttp also provides support for PUT, DELETE and HEAD. Request and Response headers are surfaced as properties, so instead of having to add headers manually, we can just assign them individually (some of these are surfaced from the existing WebRequest).
Summary
That’s pretty much all there is to it. As I mentioned, I’ve been using it myself to talk to CouchDB, as part of YouTrackSharp and a few other projects. It’s far from feature complete, but I’m adding things as I or the few that are using it request them.
Feel free to download it and play with it. The source code is on GitHub and Issue Tracker is on CodeBetter. If you are interested in running the tests, you will need CouchDB. I originally wrote this because I needed to do some things for CouchDB and it served as a good platform for testing different Http Verbs (yes, they are integrations tests and not unit tests).