SkillAgentSearch skills...

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/Refit
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Refit

Refit: The automatic type-safe REST library for .NET Core, Xamarin and .NET

Build codecov

||Refit|Refit.HttpClientFactory|Refit.Newtonsoft.Json| |-|-|-|-| |NuGet|NuGet|NuGet|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?

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 IApiResponse and were catching these exceptions directly, you will need to update your code to catch ApiRequestException instead.
  • If you were wrapping responses with IApiResponse, these exceptions will no longer be thrown and will instead be captured in the IApiResponse.Error property. You can use the new IApiResponse.HasRequestError(out var apiRequestException) method to safely check and retrieve the ApiRequestException instance.

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

View on GitHub
GitHub Stars9.4k
CategoryDevelopment
Updated1d ago
Forks782

Languages

C#

Security Score

100/100

Audited on Mar 27, 2026

No findings