Sunday, August 18, 2019

A Few Great Ways to Consume RESTful APIs in C#

What Is a RESTful API?

So, before we start, you might be wondering what does API stand for, and what is the RESTful part all about?
To put things simply, APIs are the layers between software applications. You can send the request to the API, and, in return, you get the response from it. APIs hide all the nitty-gritty details of the concrete implementation of a software application and expose the interface you should use to communicate with that application.
The whole internet is one big spider web made of APIs. We use APIs to communicate and relate information between applications. We have an API for pretty much anything out there. Most of the services you use daily have their own APIs (GoogleMaps, Facebook, Twitter, Instagram, weather portals...)
The RESTful part means that the API is implemented in accordance with the principles and rules of REST (Representational State Transfer) which is the underlying architectural principle of the web. RESTful APIs, in most cases, return a plain text, JSON, or XML response. 

How to Consume RESTful APIs

Ok, let's go to the meaty part of this whole story.
There are several ways to consume a RESTful API in C#:
  1. HttpWebRequest/Response class
  2. WebClient class
  3. HttpClient class
  4. RestSharp NuGet package
  5. ServiceStack Http Utils
Every one of these has pros and cons, so let us go through them and see what they offer.
As an example, we will be collecting information about RestSharp repo releases and their publish dates via the GitHub API. This information is available publicly and you can see how raw JSON response looks here: RestSharp releases.
We are going to utilize the help of the Json.NET library to deserialize the response we get. Also, for some examples, we are going to use the inbuilt deserialization mechanisms of the libraries. It's up to you to choose which way you prefer because no way is the right way. (You can see the implementation for both mechanisms in the source code).
What I expect to get as a result of the next few examples is a deserialized JArray (for simplicity) that contains RestSharp release information. After that, we can iterate through it to get the following result.

HttpWebRequest/Response Class

It's the HTTP-specific implementation of the WebRequest class which was originally used to deal with HTTP requests, but it was made obsolete and replaced by the class.
The HttpWebRequest class offers fine-grained control over every aspect of the request making process. As you can imagine, this can be the double-edged sword and you can easily end up losing enormous amounts of time fine-tuning your requests. On the other hand, this might just be what you need for your specific case.
The HttpWebRequest class does not block the user interface, which is, I am sure you will agree with this one, pretty important.
The HttpWebResponse class provides a container for the incoming responses.
This is a simple example of how to consume an API using these classes.
var request = (HttpWebRequest)WebRequest.Create("https://api.github.com/repos/restsharp/restsharp/releases");
request.Method = "GET";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36";
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
var response = (HttpWebResponse)request.GetResponse();
string content = string.Empty;
using (var stream = response.GetResponseStream())
{
  using (var sr = new StreamReader(stream))
  {
  content = sr.ReadToEnd();
  }
}
var releases = JArray.Parse(content);
Although a simple example, it becomes much more complicated when you need to deal with more sophisticated scenarios like posting form information, authorizing, etc.

WebClient Class

This class is a wrapper around HttpWebRequest. It simplifies the process by abstracting the details of the HttpWebRequest from the developer. The code is easier to write and you are less likely to make mistakes this way. If you want to write less code, not worry about all the details, and the execution speed is a non-factor, consider using the WebClient class.
This example should give you the rough idea of how much easier is to use compared to the HttpWebRequest/HttpWebResponse approach.
var client = new WebClient();
client.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
var response = client.DownloadString("https://api.github.com/repos/restsharp/restsharp/releases");
var releases = JArray.Parse(response);
Much easier, right?
Other then the DownloadString method, the WebClient class offers a host of other useful methods to make our life easier. We can easily manipulate strings, files or byte arrays using it, and for a price of just a few milliseconds slower than the HttpWebRequest/HttpWebResponse approach.
Both the HttpWebRequest/HttpWebResponse and WebClient classes are available in the older versions of .NET. Be sure to check out MSDN if you are interested in what else WebClient has to offer.

HttpClient Class

HttpClient is the "new kid on the block," and offers some of the modern .NET functionalities that older libraries lack. For example, you can send multiple requests with the single instance of HttpClient, as it is not tied to the particular HTTP server or host and makes use of async/await mechanism.
  • Strongly typed headers.
  • Shared Caches, cook­ies, and credentials.
  • Access to cook­ies and shared cookies.
  • Con­trol over caching and shared cache.
  • Inject your code mod­ule into the ASP.NET pipeline. Cleaner and mod­u­lar code.
Here is HttpClient in action in our example:
using (var httpClient = new HttpClient())
{
  httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
  var response = httpClient.GetStringAsync(new Uri(url)).Result;
  var releases = JArray.Parse(response);
}
For the simplicity's sake, I implemented it synchronously. Every HttpClient method is meant to be used asynchronously and SHOULD be used that way.
Also, I need to mention one more thing. There is a debate whether HttpClient should be wrapped in a using block or statically on the app level. Although it implements IDisposable, it seems that by wrapping it in the using block you can make your app malfunction and get the SocketException. And as Ankit blogs, the performance test results are much in favor of static initialization of the HttpClient. Be sure to read these blog posts as they can help you be more informed about the correct use of the HttpClient class.
And don't forget, being modern, HttpClient is exclusive to the .NET 4.5, so you might have trouble using it on some legacy projects.

RestSharp

RestSharp is the OpenSource alternative to standard .NET libraries and one of the coolest .NET libraries out there. It is available as a NuGet package, and there are a few reasons why you should consider trying it out.
Like HttpClient, RestSharp is a modern and comprehensive library, easy and pleasant to use, while still having support for older versions of .NET Framework. It has inbuilt Authentication and Serialization/Deserialization mechanisms but allows you to override them with your custom ones. It is available across platforms and supports OAuth1, OAuth2, Basic, NTLM, and Parameter-based Authentication. You can choose to work both synchronously or asynchronously. There is a lot more to this library, and these are just some of the great benefits it offers. For the detailed information on usage and capabilities of RestSharp, you can visit the RestSharp page on GitHub.
Now let's try to get a list of RestSharp releases using RestSharp:
var client = new RestClient(url);
IRestResponse response = client.Execute(new RestRequest());
var releases = JArray.Parse(response.Content);
Simple enough. But do not be fooled, RestSharp is very flexible and has all the tools you need to achieve almost anything while working with RESTful API.
One thing to note in this example is that I didn't use RestSharp's deserialization mechanism due to the example consistency, which is a bit of a waste, but I encourage you to use it as it is really easy and convenient. So you can easily make a container like this:
public class Release
{
  [DeserializeAs(Name = "name")]
  public string Name { get; set; }
  [DeserializeAs(Name = "published_at")]
  public string PublishedAt { get; set; }
}
And after that, use the Execute method to directly deserialize the response to that container. You can add just the properties you need and use the attribute DeserializeAs to map them to C# properties (nice touch). Since we get the list of releases in our response, we use the List<Release> as a containing type.
var client = new RestClient(url);
var response = client.Execute<List<Release>>(new RestRequest());
var releases = response.Data;
Pretty straightforward and elegant way to get our data.
There is a lot more to RestSharp than sending GET requests, so explore and see for yourself how cool it can be.
One final note to add to the RestSharp case is that its repository is in need of maintainers. If you want to learn more about this cool library, I urge you to head over to RestSharp repo and help this project stay alive and be even better. You can also help porting RestSharp to .NET Core.

ServiceStack Http Utils

Another library, but unlike RestSharp, ServiceStack seems to be properly maintained and keeping the pace with modern API trends. The list of ServiceStack features is impressive and it certainly has various applications.
What is most useful to us here is to demonstrate how to consume an external RESTful API. ServiceStack has a specialized way of dealing with 3rd Party HTTP APIs called Http Utils.
Let us see how fetching RestSharp releases looks like using ServiceStack Http Utils first using the Json.NET parser.
var response = url.GetJsonFromUrl(requestFilter: webReq =>
{
webReq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36";
});
var releases = JArray.Parse(response);
You can also choose to leave it to the ServiceStack parser. We can reuse the Release class defined earlier in the post.
List<Release> releases = url.GetJsonFromUrl(requestFilter: webReq =>
{
webReq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36";
}).FromJson<List<Release>>();
As you can see, either way, works fine, and you can choose whether you get the string response or deserialize it immediately.
Although ServiceStack is the last library I stumbled upon. I was pleasantly surprised how easy it was for me to use it, and I think it may become my go-to tool for dealing with APIs and services in the future.

Other Options

There are a lot of other options available for your specific problems. These libraries are meant to be used for consuming a single REST service. For example, octokit.net is used to work with GitHub API specifically, Facebook SDK is used for consuming Facebook APIs, and there are many others for almost anything.
While these libraries are made specifically for those APIs and may be great at doing what they are meant for, their usefulness is limited because you often need to connect with more than one API in your applications. This may result in having different implementations for each one, and more dependencies which potentially leads to repetitiveness and is error-prone. The more specific the library, the less flexibility it has.

No comments:

Post a Comment

How to register multiple implementations of the same interface in Asp.Net Core?

 Problem: I have services that are derived from the same interface. public interface IService { } public class ServiceA : IService { ...