1 声明式 RESTful 客户端
声明式服务调用的客户端, 常见有安卓的 Retrofit,SpringCloud 的 Feign 等,.net 有 Refit 和 webApiClient, 这些客户端都是以 java 或. net 某个语言来声明接口, 描述如何请求 RESTful API.
1.1 WebApiClient
https://github.com/dotnetcore/WebApiClient 由 c# 开发, 但适用于任意. net 语言, 包括 c#,vb.NET,f# 等项目, 其提供两个 nuget 包: WebApiClient.JIT 和 WebApiClient.AOT, 均支持. net framework4.5,.NET Standard 1.3 .
WebApiClient.JIT
在运行时使用 Emit 创建 Http 请求接口的代理类, HttpApiClient.Create
可以在项目中直接引用 WebApiClient.JIT.dll 就能使用;
不适用于不支持 JIT 技术的平台 (iOS,UWP);
接口要求为 public;
WebApiClient.AOT
在编译过程中使用 Mono.Cecil 修改编译得到的程序集, 向其插入 Http 请求接口的代理类 IL 指令, 这一步是在 AOT 编译阶段之前完成. 代理类型所在的程序集, 模块, 命名空间与接口类型的一样, 其名称为 $ 前缀的接口类型名称, 使用反编译工具查看项目编译后的程序集可以看到这些代理类.
项目必须使用 nuget 安装 WebApiClient.AOT 才能正常使用;
没有 JIT, 支持的平台广泛;
接口不要求为 public, 可以嵌套在类里面;
1.2 Refit
Refit https://github.com/reactiveui/refit 是一个开发很早的项目, 在 GitHub 有很高的人气, 由 c# 开发, 目前仅支持 c# 语言项目, 支持. NET Standard 1.4,.net framework 需要 4.6.1 得以支持.
Refit 的内部实现与 WebApiClient.AOT 有相似之处, 都是在编译阶段向声明接口项目插入接口实现类的代码或 IL 指令, 我们可以称之为静态代理的编译时织入. Refit 使用 Microsoft.CodeAnalysis.CSharp 来分析接口语法, 编译前补充生成接口的代理类代码用来与项目代码一起编译.
2 WebApiClient 的声明式接口
WebApiClient 支持 GET/HEAD,PUT/POST/DELETE,PATCH 请求方法, 请求内容体支持 JSON,xml,multipart/form-data,application/x-www-form-urlencoded 和自定义无结构内容等, 其声明式接口风格与 ASP.NET core 的接口声明非常相似.
2.1 接口声明
远程服务 ASP.NET core 接口示例
- [Route("api/[controller]")]
- [ApiController]
- public class UsersController : ControllerBase
- {
- // GET API/users
- [HttpGet]
- public UserInfo[] Get()
- {
- return new UserInfo[]
- {
- new UserInfo { Account="laojiu" },
- new UserInfo { Account="webapicleint" }
- };
- }
- // GET API/users/id001
- [HttpGet("{id}")]
- public UserInfo Get(string id)
- {
- return new UserInfo { Id = id, Account = "laojiu" };
- }
- // POST API/users
- [HttpPost]
- public bool Post([FromBody] UserInfo value)
- {
- return true;
- }
- // PUT API/users
- [HttpPut]
- public bool Put([FromBody] UserInfo value)
- {
- return true;
- }
- // PATCH API/users/id001
- [HttpPatch("{id}")]
- public bool Patch(string id, [FromBody] JsonPatchDocument<UserInfo> value)
- {
- var user = new UserInfo { Account = "laojiu" };
- value.ApplyTo(user);
- return true;
- }
- // DELETE API/users/id001
- [HttpDelete("{id}")]
- public bool Delete(string id)
- {
- return true;
- }
- }
WebApiClient 声明式调用接口
- [TraceFilter]
- public interface IUsersApi : IHttpApi
- {
- [HttpGet("api/users")]
- ITask<UserInfo[]> GetAsync();
- [HttpGet("api/users/{id}")]
- ITask<UserInfo> GetAsync(string id);
- [HttpPost("api/users")]
- ITask<bool> PostAsync([JsonContent] UserInfo value);
- [HttpPut("api/users")]
- ITask<bool> PutAsync([JsonContent] UserInfo value);
- [HttpPatch("api/users/{id}")]
- ITask<bool> PatchAsync(string id, JsonPatchDocument<UserInfo> value);
- [HttpDelete("api/users/{id}")]
- ITask<bool> DeleteAsync(string id);
- }
3 WebApiClient 与 DI 结合
在 ASP.NET core 环境中, 我们可以使用项目简单 WebApiClient 的 DI 的配置, 目前有 DependencyInjection 和 HttpClientFactory 的扩展等.
3.1 WebApiClient.Extensions.DependencyInjection
引入 nuget 包
PM> install-package WebApiClient.Extensions.DependencyInjection
Startup 相关配置
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddHttpApi<IUsersApi>().ConfigureHttpApiConfig((c,p) =>
- {
- c.HttpHost = new Uri("https://localhost:5001/");
- c.FormatOptions.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";
- c.LoggerFactory = p.GetRequiredService<ILoggerFactory>();
- });
- ...
- }
- Controller
- public class HomeController : Controller
- {
- public async Task<string> Index([FromServices]IUsersApi usersApi)
- {
- var u = new UserInfo { Id = "id001", Account = "webapiclient", Password = "123456" };
- var doc = new JsonPatchDocument<UserInfo>();
- doc.Replace(item => item.Password, "888888");
- var users = await usersApi.GetAsync();
- var user = await usersApi.GetAsync("id001");
- var postState = await usersApi.PostAsync(u);
- var putState = await usersApi.PutAsync(u);
- var patchState = await usersApi.PatchAsync("id001", doc);
- var deleteState = await usersApi.DeleteAsync("id001");
- return "ok";
- }
- }
- 3.2 WebApiClient.Extensions.HttpClientFactory
引入 nuget 包
PM> install-package WebApiClient.Extensions.HttpClientFactory
Startup 相关配置
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddHttpApiTypedClient<IUsersApi>((c, p) =>
- {
- c.HttpHost = new Uri("https://localhost:5001/");
- c.FormatOptions.DateTimeFormat = "yyyy-MM-dd HH:mm:ss.fff";
- c.LoggerFactory = p.GetRequiredService<ILoggerFactory>();
- });
- ...
- }
4 总结
本文讲解了声明式客户端的概念, 列表几个声明式客户端项目, 同时讲解声明式客户端 WebApiClient 在 ASP.NET core 项目中的简单使用, 有关更多高级的应用, 可以到 WebApiClient 的 GitHub 上查看相关 wiki.
来源: https://www.cnblogs.com/kewei/p/9786319.html