Wednesday, November 6, 2013

Why Sprint.Rest client is better than RestSharp for building REST clients?



If you are interacting with any REST service then you problably have used some kind of HTTP client library. I have used RestSharp on few project. RestSharp is quite cool. You can learn more aobut RestSharp from their website. They have got an example there that talks about what you can do with Restsharp. If you have never used a library for interacting with REST services then I strongly recommend taking a look at RestSharp.

But this post is not about Restsharp. Don't get me wrong, ReshSharp is a cool and sleep library and delivers exactly what is says on the tin. There is one area though where it dis-appointed me - testability. When you are writing client code to communicate with a REST service and if you are like me, you would like that code to be unit tested. With Restsharp there is no way of mocking the actual call (or at least I did not find anything either in source code or in their documentation). Having to make real calls from the tests is a heavy affair that I would like to avoid. And I also do not want to bombard the real service with loads of requests that my client code needs to be tested for. So I was on lookout for a new REST client library. My search lead me to REST client that is part of Spring framework (not the Java one but the one built for .NET). I was amazed by the features that this library offers and immense documentation that they have got. You can find more details on their website. The part I most liked was ability to mock the service, set expectations on requests sent and return mocked responses. Let's dive into some code

Testability

One of the common tests that I write for my client is to ensure that request is being made on correct url. In case of a POST request, I also like to ensure that correct post body is being sent to server. Take a look at following test code

[Test]
public void SendsRquestOnCorrectUrl()
{
    var restTemplate = new RestTemplate("baseAddress");

    var document = new Document("master");

    var mockRestServer = MockRestServiceServer.CreateServer(restTemplate);
    mockRestServer.ExpectNewRequest()
                    .AndExpect(RequestMatchers.MatchUri(string.Format("{0}/api/document", ApiBaseUrl)))
                    .AndExpect(RequestMatchers.MatchBody(JsonConvert.SerializeObject(document)));

    restClient.PostForMessage("api/document", document);
    mockRestServer.Verify();
}

So you create an instance of RestTemplate, which is your client making HTTP connections to server. You then create an instance of mock server by calling MockRestServiceServer.CreateServer and passing in previously created instance of RestTemplate. This would now start intercepting all the calls we make using the restTemplate. Next, you set some expectations on mockRestServer. I have set following three expectations here

  1. It should expect a new request
  2. It should expect the URI on which the request would be made to match "ApiBaseUrl/api/document"
  3. It should expect the request body to contain the JSON version of document object
Then post the document object using PostForMessage method. In the end, assert the set expectations by calling Verify() method on MockRestServiceServer.

The best part is RequestMatchers class. This come bundled with loads of various matching options that you would not have to go looking for help on internet.

And more

As I used Spring Rest client more and more, I figured out there more good things about it besides testability.

  1. Less plumbing code - On most occasions, you would end up writing lesser plumbing code as compared to RestSharp.
  2. HTTP Message Conversion - Library comes packaged with several message converters that can automatically convert response data from byte array, ATOM/RSS feeds, files, strings, JSON, sliverlight etc. And if you are working with a custom response format, it is not very difficult to build and plug your own message converter. 
  3. Authentication - Besides supporting basic authentication, it support OAuth
  4. Request interceptor - This should not be confused with mocking described above. Interceptors let you inject code at various points of request life-cycle. For example, you can start a timer just before a request is sent and stop it right after response is received and calculate the response time of the server. You can implement different interceptors for different purposes.
  5. Asynch story - They have got async implementation using Task Parallel Library (TPL)
  6. and lot of other features

So far I am quite happy with this library. I have not seen many people using it so it would nice to know what you think of this library. 

No comments:

Post a Comment