Skip to content

Releases

16.4.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 16:15
92ae878

Summary

Refit 16.4.0 adds opt-in HTTP-aware retries, new query naming and relative URL options, and fixes for parameter binding and response handling. Existing clients keep their current behavior unless you enable the new options.

HTTP-aware retries

HttpRetryHandler works with Refit clients and ordinary HttpClient calls. It needs no extra resilience package or changes to your API interface.

  • By default, it allows three retries after the first send for GET, HEAD, OPTIONS and TRACE. It retries HTTP 408, 429, 500, 502, 503 and 504, plus HttpRequestException. A 403 retries only when the configured delay reader finds a valid timing hint.
  • The default reader respects standard Retry-After headers. RetryDelayProviders.Azure, .Aws, .GitHub and .Jira also read provider-specific timing headers. Custom readers can use ReadHeader with seconds, milliseconds, Unix timestamps or date formats.
  • When no valid hint is available, retries use exponential backoff starting at one second and capped at 30 seconds. Full jitter randomly spreads attempts within that interval. You can disable jitter or choose symmetric variation with RetryJitterMode.Symmetric.
  • Server hints are never shortened by jitter. A hint above MaxDelay returns the response rather than retrying too early. ServerDelayJitterRatio can add a small positive variation to a server delay.
  • Each attempt uses a fresh request with copied headers, options and content metadata. Request bodies are buffered once, with a one MiB default limit. Failed responses are disposed; the final response remains caller-owned. Cancellation covers buffering, sends and waits.

Quick start

Put the retry handler in the client's handler chain, then create your Refit client as usual:

using Refit;

var handler = new HttpRetryHandler(new HttpRetryOptions
{
    MaxRetries = 3,
    DelayProvider = RetryDelayProviders.GitHub,
})
{
    InnerHandler = new HttpClientHandler(),
};

using var client = new HttpClient(handler)
{
    BaseAddress = new Uri("https://api.github.com"),
};
var api = RestService.ForGenerated<IGitHubApi>(client);

IGitHubApi is your existing Refit interface. Omit DelayProvider to use standard Retry-After handling. With Refit.HttpClientFactory, register a fresh handler for the client:

services.AddRefitGeneratedClient<IGitHubApi>()
    .ConfigureHttpClient(static client =>
        client.BaseAddress = new Uri("https://api.github.com"))
    .AddHttpMessageHandler(static () => new HttpRetryHandler(new HttpRetryOptions
    {
        DelayProvider = RetryDelayProviders.GitHub,
    }));

Set MaxRetries = 0 to disable retries. Use ShouldRetry to replace the response rules, and BaseDelay / MaxDelay to tune waits. POST, PUT, PATCH and DELETE require RetryUnsafeMethods = true; enable this only when replay is safe for the endpoint, such as when it supports an idempotency key. Avoid unbounded streaming uploads and stacking this handler with another retry strategy.

An authentication handler inside the retry handler runs on every attempt. HttpClient.Timeout bounds the whole call, including retry waits. For deterministic tests, Refit.Testing adds RetryReply.After, RetryReply.Header and StubHttp.CreateRetryHandler, with TimeProvider support.

Other changes

  • [Query(Name = "client_id")] names a query parameter or form field. [AliasAs] still takes precedence. The positional [Query("...")] argument remains a nesting delimiter, not an alias; the new opt-in diagnostic RF016 helps catch that mistake.
  • [Url(AllowRelative = true)] accepts relative as well as absolute URLs, using normal URI resolution against HttpClient.BaseAddress. Existing encoded queries are retained when appending query parameters. Plain [Url] still requires an absolute URL.
  • RefitSettings now groups options under Serialization, Url, Exceptions and Requests. Existing top-level properties remain available and refer to the same settings. Retry options similarly expose Backoff, Replay and Responses groups.
  • The generator pipeline and model equality handling were reorganized, with added coverage for inherited interfaces, incremental generation and request construction.
  • New tested documentation recipes cover resilience and OpenTelemetry. CI now publishes and runs a consumer of the packed Refit packages under Native AOT on Windows, Linux and macOS, as well as the documentation NativeClient.
  • Dependency and build updates include ReactiveUI.Primitives 9 and refreshed test packages and GitHub Actions. Local Refit packages are excluded from Renovate updates.

Fixes

  • Route and query parameters whose names differ only by case now bind correctly in generated and reflection-based clients. Exact-case route matches take priority, and sibling query parameters no longer overwrite route values. This also covers mixed ordinary and catch-all placeholders. (#2360)
  • IApiResponse.ContentHeaders.ContentLength remains readable after response content is buffered or disposed, including when no explicit Content-Length header was sent. (#2360)
  • If response buffering fails mid-stream and deserialization then fails because the stream was consumed, Refit surfaces the original buffering exception instead of the misleading deserialization error. Content that remains readable can still be deserialized. (#2360)
  • Native AOT smoke publishing on .NET 11 RC2 no longer fails while trying to copy a missing XML documentation file. (#2360)

🗞️ What's Changed

✨ Features

🐛 Fixes

  • 8e03c5e fix: disambiguate case-differing parameters, preserve ContentLength header, and surface buffering exceptions (#2360) @glennawatson

🧹 General Changes

📦 Dependencies

  • 7c2efd1 chore(deps): update dependency tunit to 1.69.16 (#2341) renovate[bot]
  • db1db92 chore(deps): update dependency reactiveui.primitives to v9 (#2350) renovate[bot]
  • fbf8edd chore(deps): update dependency tunit to 1.72.10 (#2346) renovate[bot]
  • e692f9b chore(deps): update dependency tunit to 1.69.21 (#2343) renovate[bot]
  • 8d2e79b chore(deps): update github actions (#2353) renovate[bot]

🔗 Full Changelog: v16.3.0...v16.4.0

🙌 Contributions

💖 Thanks to all the contributors: @glennawatson

🤖 Automated services that contributed: renovate[bot]

16.3.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 07:54
053873c

🗞️ What's Changed

✨ Features

🔗 Full Changelog: v16.2.0...v16.3.0

🙌 Contributions

💖 Thanks to all the contributors: @glennawatson

16.2.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 03:06
a463e8a

🗞️ What's Changed

✨ Features

🧹 General Changes

✅ Tests

📝 Documentation

📦 Dependencies

  • b7ca029 chore(deps): update dependency reactiveui.primitives to 8.1.0 (#2334) renovate[bot]

🔗 Full Changelog: v16.1.0...v16.2.0

🙌 Contributions

💖 Thanks to all the contributors: @glennawatson

🤖 Automated services that contributed: renovate[bot]

16.1.0

Choose a tag to compare

@github-actions github-actions released this 21 Sep 04:20
bb98726

🗞️ What's Changed

✨ Features

📝 Documentation

📌 Other

🔗 Full Changelog: v16.0.0...v16.1.0

🙌 Contributions

💖 Thanks to all the contributors: @glennawatson

16.0.0

Choose a tag to compare

@github-actions github-actions released this 20 Sep 01:00
1459f55

Summary

Refit 16.0.0 is a major version because the .NET 11 assemblies are built without runtime-async. The public API does not change.

Why runtime-async is off

  • In .NET 10 and older, the C# compiler adds a state machine to each async method. The state machine stores the local variables and tracks where to resume after each await.
  • .NET 11 adds a feature called runtime-async. The runtime does this work instead, so async code can run faster.
  • Refit 12.0.0 to 15.2.0 built the .NET 11 assemblies with runtime-async on. We did not use it with older .NET 8-10 nor .NET framework assemblies.
  • The feature needs a runtime that supports it. CoreCLR does, and Mono does not.
  • Blazor WebAssembly runs on Mono unless you opt into CoreCLR. WASI, Android API levels 21 to 23, and apps that set UseMonoRuntime=true also run on Mono.
  • Refit built with runtime-async can fail in every app that runs on Mono.
  • Microsoft builds its framework assemblies twice, once for each runtime. ASP.NET Core turns the feature on only for libraries inside the shared framework, and leaves it off for libraries that also ship on NuGet.
  • A NuGet package ships one build for every runtime, so Refit leaves the feature off. The feature is opt-in, so doing nothing is the correct setting.
  • Apps that target .NET 10 or older are not affected, because only the .NET 11 assemblies used the feature. Apps on .NET 11 that run on CoreCLR do not get the speed gain inside Refit's own async code.
  • You can turn on runtime-async in your own app if it runs only on CoreCLR.

Other changes

  • Refit has a documentation website at https://reactiveui.net/documentation/refit/. It has guides for requests, results, clients, serialization and testing, and one page that lists the full API.
  • The README is a short overview of the packages, the build requirements and the links to the website.
  • src/examples/Documentation has a project for every website page, plus larger samples for topics such as multipart uploads, serializers and compression. Each project builds with Refit.slnx and checks its results against local replies, so none needs a live service.
  • On older target frameworks, Refit checks the cancellation token before it buffers or reads HTTP content. A token that is already cancelled stops the operation before it starts.
  • Doc comments were corrected to match how Refit works. They state that [Options] sends OPTIONS, that [Url] accepts an empty path or /, and that [PathPrefix] does not add a leading slash. The Refit.Testing docs state that VerifyAllCalled ignores reusable and fallback routes.
  • The Blazor WebAssembly sample builds for .NET 10 and .NET 11. It uses a generated client and JSON source generation, and builds without trimmer warnings.
  • Refit depends on ReactiveUI.Primitives 8.0.0. On .NET 11, Refit.HttpClientFactory depends on Microsoft.Extensions.Http 11.0.0-rc.1, and other targets depend on 10.0.12.
  • SECURITY.md lists the supported versions and explains how to report a vulnerability through GitHub private reporting.
  • CI workflows drop code scanning of fork pull requests and pass sourceRef to the shared release workflow. Renovate handles package updates per target framework, and the generator snapshot tests use a small in-repo helper instead of the Verify packages.

🗞️ What's Changed

✨ Features

🧹 General Changes

📝 Documentation

📦 Dependencies

  • 45fcc59 chore(deps): pin mcr.microsoft.com/dotnet/sdk docker tag to e622deb (#2324) renovate[bot]
  • 8b71ed0 chore(deps): update dependency minver to v8 (#2320) renovate[bot]
  • 2d89767 chore(deps): update dependency sonaranalyzer.csharp to 10.33.0.1635 (#2316) renovate[bot]
  • 2f75847 chore(deps): update dependency microsoft.testing.extensions.codecoverage to 18.11.2 (#2322) renovate[bot]
  • 9bf02a3 chore(deps): update dependency verify.tunit to v32 (#2318) renovate[bot]
  • 96e91c6 chore(deps): update dependency roslynator.analyzers to v5 (#2317) renovate[bot]
  • 47698c4 chore(deps): pin github actions digests (#2323) renovate[bot]
  • 5d9fe43 chore(deps): update dependency sonaranalyzer.csharp to 10.34.0.3385 (#2321) renovate[bot]
  • 38471c8 chore(deps): update dependency publicapisharp.analyzers to v2 (#2328) renovate[bot]

📌 Other

🔗 Full Changelog: v15.2.0...v16.0.0

🙌 Contributions

💖 Thanks to all the contributors: @glennawatson

🤖 Automated services that contributed: renovate[bot]

15.2.0

Choose a tag to compare

@github-actions github-actions released this 18 Aug 14:53
96316a6

🗞️ What's Changed

✨ Features

🐛 Fixes

📦 Dependencies

  • 755b8c3 chore(deps): update dependency roslynator.analyzers to 4.16.1 (#2312) renovate[bot]

🔗 Full Changelog: v15.1.0...v15.2.0

🙌 Contributions

💖 Thanks to all the contributors: @glennawatson

🤖 Automated services that contributed: renovate[bot]

15.1.0

Choose a tag to compare

@github-actions github-actions released this 15 Aug 02:03
74cbb64

🗞️ What's Changed

🐛 Fixes

⚡ Performance

🧹 General Changes

📦 Dependencies

  • 46071eb chore(deps): update dependency sonaranalyzer.csharp to 10.32.0.713 (#2303) renovate[bot]
  • 51368ea chore(deps): update dependency roslynator.analyzers to 4.16.0 (#2298) renovate[bot]

🔗 Full Changelog: v15.0.0...v15.1.0

🙌 Contributions

💖 Thanks to all the contributors: @glennawatson

🤖 Automated services that contributed: renovate[bot]

15.0.0

Choose a tag to compare

@github-actions github-actions released this 05 Aug 20:12
873c8bd

🗞️ What's Changed

✨ Features

🐛 Fixes

🧹 General Changes

📦 Dependencies

🔗 Full Changelog: v14.0.1...v15.0.0

🙌 Contributions

🌱 New contributors since the last release: @lukas, @radixy0
💖 Thanks to all the contributors: @glennawatson, @jgarciadelanoceda, @lukas, @radixy0, @rmja

🤖 Automated services that contributed: @renovate[bot]

15.0.0-beta.1

15.0.0-beta.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Aug 08:35
52345ac

🗞️ What's Changed

✨ Features

🐛 Fixes

🧹 General Changes

📦 Dependencies

🔗 Full Changelog: v14.0.1...v15.0.0-beta.1

🙌 Contributions

🌱 New contributors since the last release: @lukas, @radixy0
💖 Thanks to all the contributors: @glennawatson, @JaviergarcíadelaNocedaArgüelles, @jgarciadelanoceda, @lukas, @radixy0

🤖 Automated services that contributed: @renovate[bot]

14.0.1

Choose a tag to compare

@github-actions github-actions released this 26 Jul 23:42
132f72d

🗞️ What's Changed

🐛 Fixes

⚡ Performance

🔗 Full Changelog: v14.0.0...v14.0.1

🙌 Contributions

🌱 New contributors since the last release: @JavierGarciadelaNocedaArguelles
💖 Thanks to all the contributors: @glennawatson, @JavierGarciadelaNocedaArguelles, @JaviergarcíadelaNocedaArgüelles, @jgarciadelanoceda

⌂ 换网址