Refit
The automatic type-safe REST library for .NET Core, Xamarin and .NET. Heavily inspired by Square's Retrofit library, Refit turns your REST API into a live interface.
Install / Use
/learn @reactiveui/RefitREADME

Refit: The automatic type-safe REST library for .NET Core, Xamarin and .NET
||Refit|Refit.HttpClientFactory|Refit.Newtonsoft.Json|
|-|-|-|-|
|NuGet||
|
|
Refit is a library heavily inspired by Square's Retrofit library, and it turns your REST API into a live interface:
public interface IGitHubApi
{
[Get("/users/{user}")]
Task<User> GetUser(string user);
}
The RestService class generates an implementation of IGitHubApi that uses
HttpClient to make its calls:
var gitHubApi = RestService.For<IGitHubApi>("https://api.github.com");
var octocat = await gitHubApi.GetUser("octocat");
.NET Core supports registering via HttpClientFactory
services
.AddRefitClient<IGitHubApi>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("https://api.github.com"));
Table of Contents
- Where does this work?
- API Attributes
- Querystrings
- Body content
- Setting request headers
- Passing state into DelegatingHandlers
- Multipart uploads
- Retrieving the response
- Using generic interfaces
- Interface inheritance
- Default Interface Methods
- Using HttpClientFactory
- Providing a custom HttpClient
- Handling exceptions
Where does this work?
Refit currently supports the following platforms and any .NET Standard 2.0 target:
- UWP
- Xamarin.Android
- Xamarin.Mac
- Xamarin.iOS
- Desktop .NET 4.6.1
- .NET 6 / 8
- Blazor
- Uno Platform
SDK Requirements
Updates in 8.0.x
Fixes for some issues experienced, this lead to some breaking changes. See Releases for full details.
V6.x.x
Refit 6 requires Visual Studio 16.8 or higher, or the .NET SDK 5.0.100 or higher. It can target any .NET Standard 2.0 platform.
Refit 6 does not support the old packages.config format for NuGet references (as they do not support analyzers/source generators). You must
migrate to PackageReference to use Refit v6 and later.
Breaking changes in 6.x
Refit 6 makes System.Text.Json the default JSON serializer. If you'd like to continue to use Newtonsoft.Json, add the Refit.Newtonsoft.Json NuGet package and set your ContentSerializer to NewtonsoftJsonContentSerializer on your RefitSettings instance. System.Text.Json is faster and uses less memory, though not all features are supported. The migration guide contains more details.
IContentSerializer was renamed to IHttpContentSerializer to better reflect its purpose. Additionally, two of its methods were renamed, SerializeAsync<T> -> ToHttpContent<T> and DeserializeAsync<T> -> FromHttpContentAsync<T>. Any existing implementations of these will need to be updated, though the changes should be minor.
Updates in 6.3
Refit 6.3 splits out the XML serialization via XmlContentSerializer into a separate package, Refit.Xml. This
is to reduce the dependency size when using Refit with Web Assembly (WASM) applications. If you require XML, add a reference
to Refit.Xml.
V11.x.x
Breaking changes in 11.x
Refit 10 introduces ApiRequestException to represent requests that fail before receiving a response from the server.
This exception will now wrap previous exceptions such as HttpRequestException and TaskCanceledException when they occur during request execution.
- If you were not wrapping responses with
IApiResponseand were catching these exceptions directly, you will need to update your code to catchApiRequestExceptioninstead. - If you were wrapping responses with
IApiResponse, these exceptions will no longer be thrown and will instead be captured in theIApiResponse.Errorproperty. You can use the newIApiResponse.HasRequestError(out var apiRequestException)method to safely check and retrieve theApiRequestExceptioninstance.
The IApiResponse.Error property's type has also changed to ApiExceptionBase, which is the new base class for ApiException and ApiRequestException.
If your code accessed members specific to ApiException (i.e. anything related to the response from the server), you can use the new IApiResponse.HasResponseError(out var apiException) method to safely check and retrieve the ApiException instance.
All response-related properties of IApiResponse are now nullable.
The new IApiResponse.IsReceived property can be used to check if a response was received from the server, and will mark those properties as non-null.
The original IApiResponse.IsSuccessful and IApiResponse.IsSuccessStatusCode properties can still be used to check if the response was received and is successful.
API Attributes
Every method must have an HTTP attribute that provides the request method and relative URL. There are six built-in annotations: Get, Post, Put, Delete, Patch and Head. The relative URL of the resource is specified in the annotation.
[Get("/users/list")]
You can also specify query parameters in the URL:
[Get("/users/list?sort=desc")]
A request URL can be updated dynamically using replacement blocks and parameters on the method. A replacement block is an alphanumeric string surrounded by { and }.
If the name of your parameter doesn't match the name in the URL path, use the
AliasAs attribute.
[Get("/group/{id}/users")]
Task<List<User>> GroupList([AliasAs("id")] int groupId);
A request url can also bind replacement blocks to a custom object
[Get("/group/{request.groupId}/users/{request.userId}")]
Task<List<User>> GroupList(UserGroupRequest request);
class UserGroupRequest{
int groupId { get;set; }
int userId { get;set; }
}
Parameters that are not specified as a URL substitution will automatically be used as query parameters. This is different than Retrofit, where all parameters must be explicitly specified.
The comparison between parameter name and URL parameter is not
case-sensitive, so it will work correctly if you name your parameter groupId
in the path /group/{groupid}/show for example.
[Get("/group/{groupid}/users")]
Task<List<User>> GroupList(int groupId, [AliasAs("sort")] string sortOrder);
GroupList(4, "desc");
>>> "/group/4/users?sort=desc"
Round-tripping route parameter syntax: Forward slashes aren't encoded when using a double-asterisk (**) catch-all parameter syntax.
During link generation, the routing system encodes the value captured in a double-asterisk (**) catch-all parameter (for example, {**myparametername}) except the forward slashes.
The type of round-tripping route parameter must be string.
[Get("/search/{**page}")]
Task<List<Page>> Search(string page);
Search("admin/products");
>>> "/search/admin/products"
Querystrings
Dynamic Querystring Parameters
If you specify an object as a query parameter, all public properties which are not null are used as qu
