Introduction to Refit
When building applications that interact with external APIs, making HTTP requests efficiently is essential. Refit is a fantastic library that simplifies the process by allowing you to declare API interfaces using attributes and automatically generates REST clients for you.
What is Refit?
Refit is a REST library for .NET that turns your REST API into a live interface. Instead of manually writing HttpClient requests and handling deserialization, you can define an interface that represents your API and let Refit handle the rest.
Advantages of Refit
- Simplicity: Refit makes HTTP communication in .NET extremely simple, allowing you to focus on the business logic rather than the networking code.
- Automatic Deserialization: Refit automatically handles the serialization and deserialization of requests and responses, reducing boilerplate code.
- Attributes for Configuration: Easily define HTTP methods (GET, POST, PUT, DELETE) and endpoints with attributes on interfaces.
- Integration with Dependency Injection: Refit integrates seamlessly with ASP.NET Core’s DI system, enabling you to inject API clients into your services.
- Error Handling: It provides built-in support for handling error responses with clear and informative exceptions.
Getting Started with Refit
1. Create your API controller or use an external API
Create your API controller, i.e:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
private static List<User> users = new List<User>
{
new User { Id = 1, Name = "John Doe", Email = "john.doe@example.com" },
new User { Id = 2, Name = "Jane Doe", Email = "jane.doe@example.com" }
};
[HttpGet]
public IActionResult GetUsers()
{
return Ok(users);
}
[HttpGet("{id:int}")]
public IActionResult GetUserById(int id)
{
var user = users.FirstOrDefault(u => u.Id == id);
if (user == null)
{
return NotFound();
}
return Ok(user);
}
[HttpPost]
public IActionResult CreateUser([FromBody] User user)
{
if (user == null)
{
return BadRequest();
}
user.Id = users.Count + 1;
users.Add(user);
return CreatedAtAction(nameof(GetUserById), new { id = user.Id }, user);
}
}
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
NOTE: You can use Refit with external APIs as well.
2. Define Your API Interface
Create an interface representing your API endpoints. Use Refit attributes to declare the HTTP methods and routes.
1
2
3
4
5
6
7
8
9
10
11
12
13
using Refit;
public interface IUsersApi
{
[Get("/users")]
Task<List<User>> GetUsersAsync();
[Get("/users/{id}")]
Task<User> GetUserByIdAsync(int id);
[Post("/users")]
Task CreateUserAsync([Body] User user);
}
3. Register Refit Client in Program.cs
Refit integrates easily with .NET’s dependency injection. Register your Refit client in Program.cs
using the following code:
1
2
builder.Services.AddRefitClient<IUsersApi>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("https://yourapibaseaddress.com"));
For external APIs, the process is the same. You will define an interface for the API and create a model to map the response data. Note that you don’t need to map every field from the API response:
1
2
builder.Services.AddRefitClient<IExternalApiExample>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("https://externalbaseaddress.com"));
1
2
3
4
5
public class ExternalApiModel
{
public int Id { get; set; }
public string Name { get; set; }
}
4. Using Refit in Your Application
Now you can inject your Refit API client into your services or controllers and use it to make API calls.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class UsersService
{
private readonly IUsersApi _usersApi; // Your Refit interface here
public UsersService(IUsersApi usersApi)
{
_usersApi = usersApi;
}
public async Task<List<User>> GetAllUsersAsync()
{
return await _usersApi.GetUsersAsync();
}
public async Task<User> GetUserByIdAsync(int id)
{
return await _usersApi.GetUserByIdAsync(id);
}
public async Task CreateUserAsync(User user)
{
await _usersApi.CreateUserAsync(user);
}
}
5. Error Handling
Refit provides rich error handling support. If an API call fails, it throws an ApiException
with detailed information about the request and response.
1
2
3
4
5
6
7
8
try
{
var user = await _usersApi.GetUserByIdAsync(1);
}
catch (ApiException ex)
{
Console.WriteLine($"Request failed with status code {ex.StatusCode}");
}
6. Customizing Requests
You can add headers, query parameters, and more using attributes.
1
2
[Get("/users")]
Task<List<User>> GetUsersAsync([AliasAs("limit")] int pageSize);
7. Making Authenticated Requests
To include authentication tokens in your requests, you can use the HttpClient
setup or pass them directly in the header.
1
2
3
4
5
6
builder.Services.AddRefitClient<IUsersApi>()
.ConfigureHttpClient(c =>
{
c.BaseAddress = new Uri("https://api.example.com");
c.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "your_token_here");
});
Conclusion
Refit is an incredibly powerful tool that simplifies working with RESTful APIs in .NET. By using simple interface declarations and attributes, you can eliminate boilerplate HTTP request code and focus on building your application’s core functionality. Start using Refit in your projects today to streamline your API interactions!