Exploring Video Games With the New IHttpClientFactory In .NET Core 2.1

REST services are everywhere. It’s tough to find an application that doesn’t leverage an externally hosted REST service in some way. Prior to .NET Core 2.1, a common library that was used to perform REST requests was RestSharp. I love RestSharp, but let’s explore the new alternative IHttpClientFactory that became available as part of .NET Core 2.1.

In this demo, we’re going to cover a bunch of awesome features:

  • Simple dependency injection
  • Named instances
  • Typed clients
  • Message handlers

In addition, for this service, we’re going to leverage the Internet Game Database API to pull in some data about Nintendo Switch games. As an aside, if you don’t already own a Nintendo Switch, it’s a fantastic device for the family, for travel, or just for fun. If you want to follow along with the code, you’ll need to create a free account here. Once you have your API key, you’ll want to be sure to include that in the code. There is a host of functionality available with this API, and you could use it to start building your video game collection, embed information about games in your apps, and much more.

You may also wish to download the source code for this. It is available on Github here.

Basic Usage

To start, let’s open Visual Studio 2017 and create an ‘Empty’ project denoting ASP.NET Core 2.1 as the framework.

Once we’re up and running, let’s add a few lines to our Startup.cs class. It should look like this when we’re done. Specifically, note the new services.AddHttpClient(); extension method on IServiceCollection which is exposed in 2.1.

Next, let’s create a GameController and a Game class for the purposes of deserialization. Notice how we inject the IHttpClientFactory into the controller constructor? We then use the CreateClient() method of the factory inside the controller action to create a basic instance. A noteworthy feature for IHttpClientFactory is that it maintains a pool of reusable clients, each with a lifetime of 2 minutes by default. This keeps the overhead involved with connectivity and instantiation at a more manageable level by default which is great for our overall performance and scalability.

Named Instances

In the above code, we are defining the HttpClient inside the controller class, but it’s also possible to have a “named” instance of the HttpClient. We could re-write our line from our Startup.cs class above to use this code instead:

Then, inside our controller, we would inject the IHttpClientFactory the same way, but we would change the CreateClient() method to use our named instance.

Typed Clients

Cool stuff so far, right? Let’s take it one more step further: typed clients. Let’s add the interface and class below to our application. Note how we have a private HttpClient as part of our IgdbClient object which exposes developer friendly names for each of the Igdb.com API endpoints we can consume in our application. Note: There are plenty more fields available in this API, including artwork, screenshots, and more but we are just keeping it simple for the demo.

Finally, let’s modify our Startup class to inject our configured client for our application, and also modify our GameController class so that it exposes these two new methods for testing purposes. We’re configuring the Startup class to inject our application specific configuration (so we can distribute this class to other applications which each have their own API key, and we’re also injecting IgdbClient this into the controller.

Message Handlers

The last feature we’re going to discuss is message handlers. Handlers can be attached to clients to monitor messages as they go in, or messages as they go out. You could perform logging for messages or duration, request validation, and more. Handlers can be chained as middleware as well. We’re going to keep it simple for our demo, and simply verify that the user-key which is required for the Igdb.com API is specified for the request before it goes out for our application. Let’s add the following class to our app:

Let’s also modify our Startup class, specifically the ConfigureServices method so that the following appears after we registered our IgdbClient.

Now, if we try to call the /game/id or /game/popular endpoints without having specified our user-key, this will result in a 400 Bad Request error before it is even attempted to be sent to the Igdb API. This potentially saves us API usage limits and cost as well as improves our performance by failing before the attempt is made.

 

Kyle Ballard

Software engineer specializing in Ecommerce.