Using Refit to Consume APIs in .NET Core
What is Refit client library
Refit client is a type safe library to make HTTP calls. It lets you define your API calls using C# interfaces.
For me it is fantastic instead of writing a lot of HTTP Client configuration code.
It is available in .NET, NET Core and Xamarin
How is it different than conventional approach?
In conventional style we have to first configure HTTP client, setting base address, headers, serialization/deserialization. We write a lot of code for all this.
Refit allows us to do all this with a few lines of code making this experience more clean and less code.
How to use it in .NET 6.0?
I have created a WEB API and its controller looks like this:
using DTOS;
using Microsoft.AspNetCore.Mvc;
namespace RefitClientDemo.Controllers
{
[ApiController]
[Route("[controller]")]
public class UserController : ControllerBase
{
private static List<UserDTO> users = new()
{
new UserDTO
{
Id = Guid.NewGuid().ToString(),
Name = "Muhammad Waseem"
}
};
[HttpGet("/api/user/")]
public List<UserDTO> Get()
{
return users;
}
[HttpPost("/api/user/")]
public bool Add(UserDTO user)
{
users.Add(user);
return true;
}
}
}
Let’s add a class library now which will act like a client and then we will communicate with API using Refit.
1/ Installing Refit Nuget Packages:
Open Nuget package manager in your project and install Refit package
2/ Define Interfaces for Communication:
After installation of package define your interfaces
public interface IUser
{
[Get("/api/user/")]
Task<List<UserDTO>> GetUsersAsync();
[Post("/api/user")]
Task PostAsync(UserDTO userDTO);
}
This Get and Post is coming from Refit, that is all we need to. Let’s see now how to send requests.
3/ Sending Requests to API:
static async Task Main(string[] args)
{
string baseAddress = "https://localhost:7018";
var userAPI = RestService.For<IUser>(baseAddress);
var users = await userAPI.GetUsersAsync();
foreach (var user in users)
{
Console.WriteLine($"{user.Id} : {user.Name}");
}
}
We have two ways to call these methods either with RestService approach as demonstrated in code snippet or we can inject interface as well.
For better testing experience it is recommended to use injection approach because we can mock it.
Let’s see how to register refit service in Program file.
var baseAddress = new Uri(paymentologyOptions.BaseUrl);
Action<HttpClient> configureClient = client =>
{
ConfigureHttpClientBaseAddress(client, baseAddress);
};
services.AddRefitClient<IUserRefitAPI>()
.ConfigureHttpClient(configureClient);
4/ How to add headers: We can add headers in two ways :
-
Over Interface [ Again and again for each interface]
-
Using Delegate Handler [ Set them once for all ]
Headers Style: [Headers(“Accept: application/json”, “Content-Type: application/json”)]
public interface IUser
{
[Get("/api/user/")]
Task<List<UserDTO>> GetUsersAsync();
[Post("/api/user")]
Task PostAsync(UserDTO userDTO);
}
Delegate Handler Style:
Before moving to delegating handler let’s define our header name and values.
public static class DefaultHeader
{
public static string AcceptHeaderName = "Accept";
public static string AcceptHeaderValue = "application/json";
}
Now we can use it in like this:
public class AddDefaultHeader : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Clear();
request.Headers.Add(DefaultHeader.AcceptHeaderName, DefaultHeader.AcceptHeaderValue);
return await base.SendAsync(request, cancellationToken);
}
}
Add delegating handler in RefitClent service:
services.AddRefitClient<ISomeRefitAPI>()
.ConfigureHttpClient(configureClient)
.AddHttpMessageHandler<AddDefaultHeader>();
GitHub Demo Code
Get demo code of Refit Client at this GitHub Repo
Whenever you're ready, there are 3 ways I can help you:
- Subscribe to my youtube channel : For in-depth tutorials, coding tips, and industry insights.
- Promote yourself to 9,000+ subscribers : By sponsoring this newsletter
- Patreon community : Get access to all of my blogs and articles at one place