SyZero.Feign
1.1.4-dev.1
See the version list below for details.
dotnet add package SyZero.Feign --version 1.1.4-dev.1
NuGet\Install-Package SyZero.Feign -Version 1.1.4-dev.1
<PackageReference Include="SyZero.Feign" Version="1.1.4-dev.1" />
<PackageVersion Include="SyZero.Feign" Version="1.1.4-dev.1" />
<PackageReference Include="SyZero.Feign" />
paket add SyZero.Feign --version 1.1.4-dev.1
#r "nuget: SyZero.Feign, 1.1.4-dev.1"
#:package SyZero.Feign@1.1.4-dev.1
#addin nuget:?package=SyZero.Feign&version=1.1.4-dev.1&prerelease
#tool nuget:?package=SyZero.Feign&version=1.1.4-dev.1&prerelease
SyZero.Feign
基于 Refit 的声明式 HTTP/gRPC 客户端组件,用于微服务间的远程调用。
📦 安装
dotnet add package SyZero.Feign
✨ 特性
- 🚀 声明式调用 - 通过接口定义远程服务调用
- 🔐 自动认证 - 自动传递 JWT Token 到远程服务
- 🔄 服务发现 - 与服务注册中心(Consul/Nacos/Local/DB/Redis)集成
- 📦 统一响应处理 - 自动解析标准响应格式
- ⚡ Fallback 支持 - 支持服务降级处理
- 🌐 多协议支持 - 支持 HTTP 和 gRPC 协议
- 🔌 可扩展架构 - 支持自定义协议扩展
🚀 快速开始
1. 定义服务接口
在共享项目中定义服务接口(继承 IApplicationService):
// IUserAppService.cs(共享项目)
public interface IUserAppService : IApplicationService
{
[Get("/GetUser")]
Task<UserDto> GetUserAsync(long id);
[Post("/CreateUser")]
Task<UserDto> CreateUserAsync([Body] CreateUserDto input);
[Put("/UpdateUser")]
Task<UserDto> UpdateUserAsync(long id, [Body] UpdateUserDto input);
[Delete("/DeleteUser")]
Task DeleteUserAsync(long id);
}
2. 实现 Fallback
为接口实现 Fallback 类(服务降级):
// UserAppServiceFallback.cs
public class UserAppServiceFallback : IUserAppService, IFallback
{
public Task<UserDto> GetUserAsync(long id)
{
// 降级处理:返回默认值或抛出异常
throw new Exception("用户服务暂不可用");
}
public Task<UserDto> CreateUserAsync(CreateUserDto input)
{
throw new Exception("用户服务暂不可用");
}
// ... 其他方法
}
3. 配置 Feign
在 appsettings.json 中添加 Feign 配置:
{
"Feign": {
"Service": [
{
"ServiceName": "UserService",
"DllName": "MyApp.Application.Contracts",
"Protocol": "Http",
"Timeout": 30,
"Retry": 3
},
{
"ServiceName": "OrderService",
"DllName": "MyApp.Order.Contracts",
"Protocol": "Grpc",
"EnableSsl": true,
"MaxMessageSize": 4194304
}
],
"Global": {
"Protocol": "Http",
"Strategy": "RoundRobin",
"Retry": 3,
"Timeout": 30,
"EnableSsl": false,
"MaxMessageSize": 0
}
}
}
配置说明:
| 字段 | 说明 | 默认值 |
|------|------|--------|
| ServiceName | 服务注册中心中的服务名称 | 必填 |
| DllName | 包含服务接口的程序集名称 | 必填 |
| Protocol | 通信协议:Http 或 Grpc | Http |
| Strategy | 负载均衡策略 | - |
| Retry | 重试次数 | 0 |
| Timeout | 超时时间(秒) | 30 |
| EnableSsl | 是否启用 SSL/TLS | false |
| MaxMessageSize | 最大消息大小(字节),主要用于 gRPC | 0(使用默认值) |
4. 注册服务
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// 添加 Feign 服务
builder.Services.AddSyZeroFeign();
var app = builder.Build();
app.Run();
5. 使用远程服务
public class OrderService
{
private readonly IUserAppService _userService;
public OrderService(IUserAppService userService)
{
_userService = userService;
}
public async Task<OrderDto> CreateOrderAsync(CreateOrderDto input)
{
// 调用远程用户服务
var user = await _userService.GetUserAsync(input.UserId);
if (user == null)
{
throw new Exception("用户不存在");
}
// 创建订单逻辑...
}
}
📖 Refit 特性说明
HTTP 方法
public interface IProductAppService : IApplicationService
{
[Get("/products/{id}")]
Task<ProductDto> GetAsync(long id);
[Get("/products")]
Task<List<ProductDto>> GetListAsync([Query] int pageIndex, [Query] int pageSize);
[Post("/products")]
Task<ProductDto> CreateAsync([Body] CreateProductDto input);
[Put("/products/{id}")]
Task<ProductDto> UpdateAsync(long id, [Body] UpdateProductDto input);
[Delete("/products/{id}")]
Task DeleteAsync(long id);
[Patch("/products/{id}")]
Task<ProductDto> PatchAsync(long id, [Body] PatchProductDto input);
}
参数绑定
public interface ISearchAppService : IApplicationService
{
// 路径参数
[Get("/items/{category}/{id}")]
Task<ItemDto> GetItemAsync(string category, long id);
// 查询参数
[Get("/search")]
Task<List<ItemDto>> SearchAsync([Query] string keyword, [Query] int page);
// 请求体
[Post("/items")]
Task<ItemDto> CreateAsync([Body] CreateItemDto input);
// 请求头
[Get("/items")]
Task<List<ItemDto>> GetItemsAsync([Header("X-Custom-Header")] string customHeader);
// 表单数据
[Post("/upload")]
Task UploadAsync([Body(BodySerializationMethod.UrlEncoded)] Dictionary<string, string> formData);
}
🔧 高级用法
多协议支持
Feign 支持 HTTP 和 gRPC 两种协议:
HTTP 协议(默认)
基于 Refit 实现,适用于 RESTful API:
{
"ServiceName": "UserService",
"DllName": "MyApp.User.Contracts",
"Protocol": "Http"
}
gRPC 协议
基于 Grpc.Net.Client 实现,适用于高性能 RPC 调用:
{
"ServiceName": "OrderService",
"DllName": "MyApp.Order.Contracts",
"Protocol": "Grpc",
"EnableSsl": false,
"MaxMessageSize": 4194304
}
gRPC 客户端命名约定:
- 接口
IXxxService对应客户端XxxService.XxxServiceClient - 接口
IXxx对应客户端Xxx.XxxClient
自定义协议扩展
实现 IFeignProxyFactory 接口可以添加自定义协议:
public class WebSocketProxyFactory : IFeignProxyFactory
{
public FeignProtocol Protocol => (FeignProtocol)2; // 自定义协议枚举值
public object CreateProxy(Type targetType, string endPoint, FeignService feignService, IJsonSerialize jsonSerialize)
{
// 实现自定义协议代理创建逻辑
}
}
// 注册自定义协议工厂
FeignServiceRegistrar.RegisterProxyFactory(new WebSocketProxyFactory());
自定义 API 路由
使用 [Api] 特性自定义控制器名称:
[Api("custom-users")] // 路由将变为 /api/{ServiceName}/custom-users/...
public interface IUserAppService : IApplicationService
{
[Get("/info")]
Task<UserDto> GetInfoAsync();
}
处理管道
Feign 使用三层处理管道:
- RequestFeignHandler - 处理请求 URL 构建
- AuthenticationFeignHandler - 添加认证头(Bearer Token)
- ResponseFeignHandler - 解析标准响应格式
请求 → RequestHandler → AuthenticationHandler → ResponseHandler → 远程服务
响应格式
Feign 自动解析标准响应格式:
{
"code": 0,
"msg": "success",
"data": { ... }
}
code = 0时自动提取data字段返回code != 0时抛出SyMessageException异常
🔗 与其他组件集成
与 Consul 配合使用
// 注册 Consul 服务发现
builder.Services.AddSyZeroConsul();
// 注册 Feign
builder.Services.AddSyZeroFeign();
与 Nacos 配合使用
// 注册 Nacos 服务发现
builder.Services.AddSyZeroNacos();
// 注册 Feign
builder.Services.AddSyZeroFeign();
📁 项目结构
SyZero.Feign/
├── FeignOptions.cs # Feign 配置选项(包含协议枚举)
├── FeignServiceRegistrar.cs # 服务注册器
├── SyZeroFeignExtension.cs # 依赖注入扩展方法
├── AuthenticationFeignHandler.cs # 认证处理器(添加 JWT Token)
├── RequestFeignHandler.cs # 请求处理器(构建 URL)
├── ResponseFeignHandler.cs # 响应处理器(解析响应)
└── Proxy/
├── IFeignProxyFactory.cs # 代理工厂接口(扩展点)
├── FeignProxyFactoryManager.cs # 工厂管理器
├── HttpProxyFactory.cs # HTTP 协议实现(基于 Refit)
└── GrpcProxyFactory.cs # gRPC 协议实现(基于 Grpc.Net.Client)
⚠️ 注意事项
- Fallback 必须实现 - 每个远程服务接口必须有对应的 Fallback 实现类
- DllName 配置 - 确保
DllName与包含服务接口的程序集名称完全一致 - 服务发现 - 使用 Feign 前需先注册服务发现组件(Consul/Nacos/Local/DB/Redis)
- Token 传递 - 自动传递当前会话的 JWT Token 到远程服务
- 接口定义 - 服务接口必须继承
IApplicationService - gRPC 非 SSL - 使用非 SSL 的 gRPC 时,会自动启用 HTTP/2 非加密支持
- gRPC 通道复用 - gRPC 通道会被缓存复用,提高性能
- 全局配置 -
Global中的配置会被服务级配置覆盖
📄 许可证
MIT License - 详见 LICENSE
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Grpc.Net.Client (>= 2.67.0)
- Refit.Newtonsoft.Json (>= 8.0.0)
- SyZero (>= 1.1.4-dev.1)
- SyZero.Web.Common (>= 1.1.4-dev.1)
-
net6.0
- Grpc.Net.Client (>= 2.67.0)
- Refit.Newtonsoft.Json (>= 8.0.0)
- SyZero (>= 1.1.4-dev.1)
- SyZero.Web.Common (>= 1.1.4-dev.1)
-
net8.0
- Grpc.Net.Client (>= 2.67.0)
- Refit.Newtonsoft.Json (>= 8.0.0)
- SyZero (>= 1.1.4-dev.1)
- SyZero.Web.Common (>= 1.1.4-dev.1)
-
net9.0
- Grpc.Net.Client (>= 2.67.0)
- Refit.Newtonsoft.Json (>= 8.0.0)
- SyZero (>= 1.1.4-dev.1)
- SyZero.Web.Common (>= 1.1.4-dev.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.4 | 95 | 1/2/2026 |
| 1.1.4-dev.2 | 41 | 1/2/2026 |
| 1.1.4-dev.1 | 43 | 12/30/2025 |
| 1.1.3 | 87 | 12/30/2025 |
| 1.1.3-dev.6 | 42 | 12/30/2025 |
| 1.1.3-dev.3 | 121 | 1/19/2024 |
| 1.1.3-dev.2 | 177 | 11/3/2023 |
| 1.1.3-dev.1 | 182 | 3/21/2023 |
| 1.1.2 | 394 | 3/15/2023 |
| 1.1.2-dev.108.29344 | 182 | 3/15/2023 |
| 1.1.2-dev.108.28054 | 173 | 3/15/2023 |
| 1.1.2-dev.108.27487 | 178 | 3/15/2023 |
| 1.1.1 | 347 | 3/15/2023 |
| 1.1.1-dev.108.14980 | 177 | 3/15/2023 |
| 1.1.1-dev.108.13289 | 180 | 3/15/2023 |
| 1.1.1-dev.107.27144 | 172 | 3/14/2023 |
| 1.1.0 | 322 | 3/14/2023 |
| 1.1.0-workflow-dev.107.22552 | 182 | 3/14/2023 |
| 1.1.0-workflow-dev.107.21746 | 181 | 3/14/2023 |
| 1.1.0-workflow-dev.107.21506 | 186 | 3/14/2023 |
| 1.1.0-workflow-dev.107.20979 | 175 | 3/14/2023 |
| 1.1.0-dev.107.26364 | 176 | 3/14/2023 |
| 1.1.0-dev.107.24396 | 185 | 3/14/2023 |
| 1.1.0-dev.107.22787 | 175 | 3/14/2023 |
| 1.0.6 | 420 | 3/5/2022 |