In this post, you’ll learn how to create REST API clients quickly in .NET.
.NET has a well-known HttpClient class for sending HTTP requests and receiving HTTP responses. It’s a powerful and flexible tool.
Yet, manually handling URL construction, request setup, and response handling can be daunting, often resulting in verbose and less readable code. Let’s explore a more efficient approach.
What is Refit?
Refit is a .NET library designed to make interacting with RESTful APIs easy and efficient. With features like type safety, easy setup, and extensibility, Refit can save you time and reduce boilerplate code in your projects.
Getting Started with Refit
To get started with Refit, install it via NuGet:
Install-Package Refit
Basic setup
Let’s assume we have a simple Users API with two endpoints:
- GET User by ID
- POST new User
To use Refit, you need to define the interface with methods corresponding to the endpoints.
using Refit;
public interface IUsersApi
{
[Get("/api/users/{userId}")]
Task<User> GetUser(int userId);
[Post("/api/users")]
Task AddUser([Body] NewUser user);
}
public record User(
int Id,
string Name,
string Email);
public record NewUser(
string Name,
string Email);
Then, create a client:
var usersApi = RestService.For<IUsersApi>("https://localhost:7014");
And call the API:
User user = await usersApi.GetUser(1);
NewUser newUser = new("Oleg", "me@okyrylchuk.dev");
await usersApi.AddUser(newUser);
That’s it! Super easy!
Registering via HttpClientFactory
Refit supports registering HTTP clients via HttpClientFactory. To do so, you need to install an additional package, Refit.HttpClientFactory.
Install-Package Refit.HttpClientFactory
Then, you need to register the HTTP client.
builder.Services
.AddRefitClient<IUsersApi>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("https://localhost:7014"));
After that, you can get the HTTP client using constructor injection.
More about HttpClientFactory you can read in my post How to Use HttpClient Properly in .NET.
Error Handling
By default, Refit throws an ApiException when processing the response and any errors that occur when attempting to deserialize it.
However, Refit can catch the exception and return an API response for you. All you need to return Task<IApiResponse>, Task<IApiResponse<T>>, or Task<ApiResponse<T>> instead of Task<T>.
IApiResponse<User> response = await usersApi.GetUser(1);
if (response.IsSuccessStatusCode)
Console.WriteLine(response.Content); // <= User object
else
Console.WriteLine(response.Error.Message);
public interface IUsersApi
{
[Get("/api/users/{userId}")]
Task<IApiResponse<User>> GetUser(int userId);
[Post("/api/users")]
Task<IApiResponse> AddUser([Body] NewUser user);
}
Summary
Refit has many other features, making it very flexible. The documentation lists all the features.
It’s very easy to get started with Refit. You define your API using an interface and attributes, which makes code simple and more readable.
Refit gives type safety. It reduces runtime errors and makes refactoring easier.
Refit saves you a lot of time from writing boilerplate code. You don’t need to worry about HTTP communication, building requests, and handling responses.
Refit clients are easy to modify and scale. Adding a new endpoint is just adding a new method in the interface.
Refit clients are perfect for tests as you can quickly mock the client.
If you like Refit, consider giving a star for the project or contributing to project development.
Pingback: How to Use HttpClient Properly in .NET - Oleg Kyrylchuk