An issue often faced when writing a client for an API, is how to best go about programmatically when interacting with it. You could write your own HttpClient calls, use a 3rd-party library like RESTSharp, or hope that someone has already produced an SDK for your target client language/framework. In this case .NET. Refit steps in to solve the problem of SDK development. Inspired by Square’s Retrofit library, Refit turns a REST API into a live interface.
In this blog post, I will walk you through creating both a basic SDK and client for a Todo Item API. This example assumes that a company has created the Todo API and SDK, while the client would be built by an external user.
Note: All example code for this post can be found at https://github.com/seanmcgettrick/RefitSdkDemo.
The purpose of this post is primarily for SDK development, as opposed to API, so I will briefly go over the API being used in this example:
This project contains versioned request and response classes as well as a class to hold all our API routes. In a real-world example, this project would exist as a NuGet package. It may seem overkill to do this for a project with one controller and a handful of endpoints, when it comes time to create the SDK and client you will see how having the requests and responses in their own project, simplifies the process.
This project is a .NET Core 3.1 Web API with a SQL Server (localdb) database.
To begin, we will create an empty class library project to house our SDK. Next, remove the default Class1.cs and add in the ApiContracts project as a reference, as well as the Refit NuGet package.
Each controller in your API should map to an interface in your SDK. Our API only has one controller, TodosController, with the following endpoints:
Let’s create an interface for this controller. First, add a new interface named ITodoApi in the SDK project. The interface will look very similar to our controller above. For example, to create our GetAll SDK call, add the following to ITodoApi:
The Get attribute comes from the Refit package and functions in the same manner as the HttpGet attribute in our controller. Please note, however, that for Refit, we have to supply the route as a literal string. Trying to reference the ApiRoutes class will result in an error at runtime when building the client.
GetAllAsync returns a list of TodoResponse objects wrapped in Refit’s ApiResponse class. The ApiResponse class contains the following properties:
When writing a client using our new SDK development process, our TodoResponse object will be stored in the Content property which we will look at in the next section.
To complete our interface, we add the remaining endpoints:
We now have developed a basic SDK for our Todo API. All that’s left is to create our client.
Create a .NET Console application and add a project reference to our new SDK:
In Program.cs, update the signature of Main to async since we will be making asynchronous calls to our API. The next step is to create our API client class:
Note: You will need to find the port Visual Studio has assigned to your API when specifying the hostUrl. In this case, it is 44311.
Now that the client has been created, we can walk through creating, retrieving, updating, and deleting a todo item. You will notice that our requests and responses all follow a similar pattern.
Create a Todo
Update a Todo
Delete a Todo
Retrieving all Todos
Testing the SDK Client
To test the client first start your Web API project, and then run the console application. You can set breakpoints at each step if you like and monitor the database to see the todo item being created, updated, and deleted. Otherwise, you will see an output as such:
Just as an example, I have also included a project named RefitSdkDemo.PlainClient which demonstrates how a consumer of the API would have to structure a create todo item request without the benefit of our new SDK:
And since we do not have access to the SDK, the CreateTodoRequest and CreateTodoResponse classes would have to be built by the downstream consumer, and would possibly need to be updated for newer API versions.
As you can see, Refit makes it quite fast and easy to build a strongly-typed SDK for your Web API. And since Refit targets .NET Standard 2.0, you can use it almost anywhere. It is also worth mentioning, that while we did not dive into it in this blog post, Refit does support adding custom headers to requests including OAuth bearer tokens.