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.
MIT License
Bot releases are hidden (Show)
Published by clairernovotny over 6 years ago
Bugfix release with two main fixes:
Published by clairernovotny over 6 years ago
New feature release of Refit with the following notable enhancements:
ApiResponse<T>
)These were possible because of contributions from the community, thank you!
Doc updates forthcoming.
Full list of fixes: https://github.com/paulcbetts/refit/milestone/6?closed=1
Published by clairernovotny about 7 years ago
This version adds many bug fixes since the last release and has the following notable new features:
dotnet build
. This support requires the .NET Core 2 SDK and will not work with the 1.x SDK. Projects can still target any supported target frameworkPublished by anaisbetts about 9 years ago
Release notes soon
Published by anaisbetts over 9 years ago
Methods decorated with Multipart
attribute will be submitted with multipart content type.
At this time, multipart methods support the following parameter types:
For byte array and Stream parameters, use AttachmentName
parameter attribute to specify the
name for the attachment. For FileInfo
parameters, the file name will be used.
public interface ISomeApi
{
[Multipart]
[Post("/users/{id}/photo")]
Task UploadPhoto(int id, [AttachmentName("photo.jpg")] Stream stream);
}
Published by anaisbetts over 9 years ago
Bug Fixes:
Published by anaisbetts almost 10 years ago
Refit now allows you to control JSON serialization, via passing in a new RefitSettings
type into RestService.For<T>
:
var gitHubApi = RestService.For<IGitHubApi>("https://api.github.com",
new RefitSettings {
JsonSerializerSettings = new JsonSerializerSettings {
ContractResolver = new SnakeCasePropertyNamesContractResolver()
}
});
Refit now prints diagnostic information inside VS when an interface can't be generated
Published by anaisbetts almost 10 years ago
Thanks to @bennor, you can now define generic interfaces that apply to multiple APIs:
public interface IReallyExcitingCrudApi<T, in TKey> where T : class
{
[Post("")]
Task<T> Create([Body] T paylod);
[Get("")]
Task<List<T>> ReadAll();
[Get("/{key}")]
Task<T> ReadOne(TKey key);
[Put("/{key}")]
Task Update(TKey key, [Body]T payload);
[Delete("/{key}")]
Task Delete(TKey key);
}
// Later, in another part of town...
var userApi = RestService.For<IReallyExcitingCrudApi<User, string>>("http://api.example.com/users");
var adminApi = RestService.For<IReallyExcitingCrudApi<Admin, string>>("http://api.example.com/admins");
Thanks to @carl-berg, types that are serialized in the URL query string can now define custom formatting, via a new RefitSettings
class that is optionally passed to RestService.For
.
Published by anaisbetts about 10 years ago
Because of the compile-time code generation mentioned above, Refit 2.0 now has full support for WinRT (Windows Store) and Windows Phone 8.1 Universal applications too!
Published by anaisbetts about 10 years ago
2.0.1 is an Oops release to fix a PLib packaging issue as well as bump the NuGet package versions. This release also saves some space by removing unnecessary PDBs.
Published by anaisbetts about 10 years ago
Refit 2.0 uses a completely different system to generate the backing classes for your interfaces. In Refit 1.0, these classes would be generated at runtime using Castle.Core, which worked on most platforms, but fails on any Ahead-of-Time compiled platform, such as Xamarin.iOS.
Refit 2.0 instead generates classes at compile-time, by analyzing your app's source files with Roslyn, and generates a new RefitStubs.cs
file that will be compiled along with your class. As well as enabling Xamarin.iOS support, this class is easily subclassed and extended via partial classes, so customizing individual method behavior is now much easier
Observables in Refit 1.x are backed by AsyncSubject
, meaning that they replay a single result to subscribers, even after the network request ends. In Refit 2.0, Observables now do no work until Subscribed to, and each Subscription will generate a new network request, in line with Retrofit. Observables in Refit 2.0 now also will cancel network operations if the Subscription is disposed, allowing you to efficiently cancel requests if they are no longer needed.
Before:
var observable = someRestService.ReturnsAnObservable();
var result1 = await observable;
var result2 = await observable;
// result2 is just a replayed result1, the network request was made when
// we called ReturnsAnObservable regardless if anyone cared.
result1 == result2;
>>> true
After:
// Does nothing
var observable = someRestService.ReturnsAnObservable();
// Makes a web request
var result1 = await observable;
// Makes a *different* web request
var result2 = await observable;
result1 == result2;
>>> maybe?
When POSTing bodies serialized via BodySerializationMethod.UrlEncoded
, the AliasAs
tag now also works on properties in the model class:
Before:
public interface IMeasurementProtocolApi
{
[Post("/collect")]
Task Collect([Body(BodySerializationMethod.UrlEncoded)] Measurement measurement);
}
public class Measurement
{
public string t { get; set; } // This isn't even the worst of them
}
await api.Collect(new Measurement { t = "what even is t?" });
After:
// This part doesn't change
public interface IMeasurementProtocolApi
{
[Post("/collect")]
Task Collect([Body(BodySerializationMethod.UrlEncoded)] Measurement measurement);
}
// This stuff does
public Measurement
{
[AliasAs("t")]
public string Type { get; set; }
}
await api.Collect(new Measurement { Type = "event" });
Published by anaisbetts about 10 years ago
public interface IDummyHttpApi
{
[Get("/bar/{id}")]
Task<string> FetchSomeStuff(int id);
[Get("/bar/{id}?baz=bamf")]
Task<string> FetchSomeStuffWithHardcodedQueryParameter(int id);
}
RestService.For<IDummyHttpApi>("http://api.com/foo")
public interface IDummyHttpApi
{
[Get("/bar/{image}/{width}x{height}")]
Task<byte[]> GetImageData(string image, int width, int height);
}
public interface IDummyHttpApi
{
[Post("/foo/bar/{id}")]
IObservable<string> PostSomeUrlEncodedStuff([AliasAs("id")] int anId, [Body(BodySerializationMethod.UrlEncoded)] Dictionary<string, string> theData);
}
Published by anaisbetts over 10 years ago
Thanks to @bennor, Refit now supports adding request headers to both individual methods as well as to entire classes via the [Header]
attribute. Here's an example:
[Headers("X-Emoji: :rocket:")]
public interface IGitHubApi
{
[Get("/users/list")]
Task<List> GetUsers();
[Get("/users/{user}")]
[Headers("X-Emoji: :smile_cat:")]
Task<User> GetUser(string user);
[Post("/users/new")]
[Headers("X-Emoji: :metal:")]
Task CreateUser([Body] User user, [Header("X-Emoji")] string emoji);
}
Published by anaisbetts over 10 years ago
Thanks to @dahlbyk, methods can return Task
for HTTP requests that don't have a response with any information (i.e. "DeleteXYZ" that only signals if it worked or not)
Published by anaisbetts about 11 years ago
Initial Release