WebApiClient Documentation
repository·master·Indexed 24 days ago
https://github.com/dotnetcore/webapiclientA high-performance REST API client library for .NET that uses C# interface declarations to simplify API consumption. It offers two versions: WebApiClientCore for .NET Standard 2.1 (recommended) and a legacy version for .NET Standard 2.0. Key features include optimizations for .NET 8 AOT and trimming, JSON-RPC support via WebApiClientCore.Extensions.JsonRpc, Newtonsoft.Json integration, OAuth token management, and an OpenAPI source generator for automatic interface creation.
What's inside WebApiClient
- WebApiClient is a high-performance REST API library for .NET designed to provide better functionality, performance, and scalability compared to Refit. It allows developers to define API clients using semantic C# interface declarations and supports advanced features like AOT publishing, diverse serialization, and aspect-oriented programming.
Use WebApiClientCore.Extensions.OAuths for token management
masterTheWebApiClientCore.Extensions.OAuthsextension provides easy support for obtaining, refreshing, and applying OAuth tokens within your WebApiClientCore integration. It automates the lifecycle of authentication tokens to ensure your API requests remain authorized.Understand the WebApiClient App structure
masterThe
Appproject serves as a demonstration of how to implement both a server and a client within a single process. It demonstrates the following architectural roles:Server Side (服务端)
- Controllers: Act as the server endpoints.
- TokensController: Simulates a token issuance service.
- UsersController: Simulates a user resource server.
Client Side (客户端)
ApiClients.IUserApi: A declarative interface defined usingWebApiClientCorefeatures.ApiClients.UserService: A wrapper service that encapsulates the logic and has theIUserApiinterface injected into it.ApiClients.UserHostedService: A background service (IHostedService) that retrieves an instance ofUserServiceupon startup to execute tasks.
Choose between WebApiClientCore and WebApiClient
masterWebApiClient provides two distinct versions depending on your target framework and architectural needs:
- WebApiClientCore: The modern version based on
.NET Standard 2.1. It is designed to integrate seamlessly with modern .NET abstractions, includingDependency Injection,Configuration,Options, andLogging. This is the recommended version for new projects. - WebApiClient (
WebApiClient.JIT,WebApiClient.AOT): The legacy version based on.NET Standard 2.0. It supports.NET Core 2.0+and.NET Framework 4.5+. Note that this version is no longer receiving active updates.
- WebApiClientCore: The modern version based on
Key Features of WebApiClient
masterWebApiClient provides several core capabilities for building REST clients:
- Semantic Declarations: Define clients by simply declaring interfaces.
- Diverse Serialization: Supports JSON, XML, Form, and custom serialization methods.
- AOT & Trimming: Fully supports .NET 8 code trimming and Ahead-of-Time (AOT) compilation.
- Aspect-Oriented Programming (AOP): Supports interceptors, filters, logging, retries, and custom caching.
- Syntax Analysis: Provides syntax analysis and hints for interface declarations to prevent incorrect usage.
- Authentication Support: Includes extension packages for OAuth2 and token management to simplify identity authentication and authorization.
- Automatic Code Generation: A
dotnet toolcan parse local or remote OpenAPI documents to automatically generateWebApiClientCoreinterface code. - High Performance: Benchmarked to be up to 2.X times faster than Refit in various request scenarios.
Use WebApiClientCore.OpenApi.SourceGenerator to generate interface code
masterWebApiClientCore.OpenApi.SourceGenerator is a tool that parses local or remote OpenAPI (Swagger) JSON documents and generates declarative
WebApiClientCoreinterface definition code files.It follows a workflow of parsing the OpenAPI document via NSwag, processing it through RazorEngine templates, and extracting the resulting code using XDocument to produce formatted C# interface files.
Use ITask for retries and error handling
masterWhile
Task<T>is suitable for simple requests, useITask<T>when you need conditional retries or specialized error handling.Retry Strategies
- Basic:
task.Retry(count) - Fixed Delay:
task.Retry(count, TimeSpan) - Dynamic/Exponential Backoff:
task.Retry(count, index => TimeSpan)
Error and Result Handling
WhenCatch<TException>: Catch specific exceptions to trigger retries or log errors.WhenResult: Trigger retries based on the success/failure of the returned result.HandleAsDefaultWhenException: Return a default value if an exception occurs.Handle: Provide a fallback mechanism usingWhenCatch.
using WebApiClientCore; // Basic retry ITask<T> task = api.GetAsync(id); await task.Retry(3); // Fixed delay await api.GetAsync(id).Retry(3, TimeSpan.FromSeconds(1)); // Dynamic delay (exponential backoff) await api.GetAsync(id).Retry(3, i => TimeSpan.FromSeconds(Math.Pow(2, i))); // Catching exceptions await api.GetAsync(id) .Retry(3) .WhenCatch<HttpRequestException>() // Catch and retry .WhenCatch<HttpRequestException>(ex => logger.LogWarning(ex)) // Catch and log .WhenCatch<HttpRequestException>(ex => ex.InnerException is SocketException); // Conditional catch // Result-based retry await api.GetAsync(id) .Retry(3) .WhenResult(r => r.Success == false) .WhenResultAsync(async r => await cacheService.IsStaleAsync(r.Version)); // Handling exceptions with defaults var user = await api.GetAsync(id).HandleAsDefaultWhenException(); var result = await api.GetAsync(id) .Handle() .WhenCatch<HttpRequestException>(() => new User { Id = "error" });- Basic:
Critical rules for WebApiClientCore API declarations
masterWhen defining your API interfaces, you must adhere to these rules to avoid runtime errors or incorrect path concatenation:
- HttpHost Suffix: The
[HttpHost]attribute value must end with a/(e.g.,[HttpHost("https://api.example.com/")]). Failure to do so will cause path concatenation errors. - HTTP Method Attributes: Every method in your interface must have an HTTP method attribute (e.g.,
[HttpGet],[HttpPost]). - Uri Parameter Position: If using the
[Uri]attribute, it must be the first parameter of the method. - Inheritance: Interfaces do not need to inherit from
IHttpApi. - Serialization: The library uses
System.Text.Jsonby default (Newtonsoft.Json is no longer a dependency).
- HttpHost Suffix: The
Use IApiParameter subtypes for complex parameters
masterTypes that implementIApiParameterare known as 'self-explanatory parameter types'. They are used to handle complex parameter scenarios that standard Attributes cannot resolve.Understand the execution order of WebApiClient attributes
masterWebApiClient uses attributes to define request and response behavior. Attributes are executed in a specific sequence depending on whether they are applied before or after the request/response cycle.
Execution Order (Before Request):
- Parameter value validation
IApiActionAttributeIApiParameterAttributeIApiReturnAttributeIApiFilterAttribute
Execution Order (After Response):
IApiReturnAttribute- Return value validation
IApiFilterAttribute
Attributes can be applied to an entire interface (affecting all methods) or to specific methods and parameters.
Share a TokenProvider across multiple interfaces
masterYou can share a single
ITokenProvideracross multiple API interfaces by using interface inheritance. Define a base interface with the[OAuthToken]attribute, and have your specific API interfaces inherit from it.[OAuthToken] public interface IBaidu { } public interface IBaidu_XXX_Api : IBaidu { [HttpGet] Task xxxAsync(); } public interface IBaidu_YYY_Api : IBaidu { [HttpGet] Task yyyAsync(); } // Register the provider for the base interface services.AddPasswordCredentialsTokenProvider<IBaidu>(o => { o.Endpoint = new Uri("http://localhost:5000/api/tokens"); o.Credentials.Client_id = "clientId"; o.Credentials.Client_secret = "xxyyzz"; o.Credentials.Username = "username"; o.Credentials.Password = "password"; });Configure Return attributes for response handling
masterReturn attributes define how the response content is mapped to .NET data models.
Rules for Return Attributes:
- Content-Type Matching: If
EnsureMatchAcceptContentTypeistrue(default), the attribute only applies if the responseContent-Typematches the attribute'sAcceptContentType. - Error Handling: If no Return attribute matches the response
Content-Type, anApiReturnNotSupportedExceptionis thrown. - Status Code Validation: If
EnsureSuccessStatusCodeistrue(default), anApiResponseStatusExceptionis thrown if the status code is not in the 200-299 range. - Priority: If multiple attributes have the same
AcceptContentType, the one with the highestAcceptQualityis used.
Implicit Defaults: Every interface has implicit Return attributes with
AcceptQuality = 0.1. To override them, declare a new attribute of the same type with a higherAcceptQuality.Available Return Attributes:
[RawReturn]: Supportsstring,byte[],Stream, andHttpResponseMessage.[JsonReturn]: UsesSystem.Text.Jsonfor serialization/deserialization.[XmlReturn]: UsesSystem.Xml.Serializationfor serialization/deserialization.[NoneReturn]: If the response status is204, returns the default value of the return type.
[Json] // .AcceptQuality = 1.0, .EnsureSuccessStatusCode = true, .EnsureMatchAcceptContentType = false Task<SpecialResultClass> DemoApiMethod();- Content-Type Matching: If