前言

声名式服务调用,己经不算是一个新鲜的话题了,毕竟都出来好些年了。

下面谈谈,最近项目中用到一个这样的组件的简单实践。

目前部分项目用到的是Refit这个组件,都是配合HttpClientFactory来使用的。

关于HttpClientFactory的一些简单介绍,可以参见官方文档,也可以看看前面的两篇比较粗略的相关介绍。

也简单介绍一下背景,目前主要有两类的API接口:

第一类是注册到Eureka中的,可以通过服务发现的方式来请求的,这里的都是新的接口。

第二类是原始的接口,不能走服务发现,只能通过直连请求的方式来调用,这里的都是些老接口。

换句话就是说,要同时兼容这两类接口。

由于用HttpClientFactory集成服务发现十分简单,所以优先选了一个本身就带有HttpClientFactory的组件--Refit。

什么是Refit

Refit是一个自动类型安全的REST库,是RESTful架构的.NET客户端实现,

它基于Attribute,提供了把REST API返回的数据转化为(Plain Ordinary C# Object,简单C#对象),POCO to JSON,网络请求(POST,GET,PUT,DELETE等)封装,内部封装使用HttpClient,前者专注于接口的封装,后者专注于网络请求的高效,二者分工协作。

我们的应用程序通过 refit请求网络,实际上是使用 refit接口层封装请求参数、Header、Url 等信息,之后由 HttpClient完成后续的请求操作,在服务端返回数据之后,HttpClient将原始的结果交给 refit,后者根据用户的需求对结果进行解析的过程。

更多细节可以参考Refit的官网

创建一个可调用的API接口

直接上控制器的代码了〜〜

// GET: api/persons
[HttpGet]
public IEnumerable<Person> Get()
{return new List<Person>{new Person{Id = 1 , Name = "catcher wong", CreateTime = DateTime.Now},new Person{Id = 2 , Name = "james li", CreateTime = DateTime.Now.AddDays(-2)}};
}// GET api/persons/5
[HttpGet("{id}")]
public Person Get(int id)
{return new Person { Id = id, Name = "name" };
}// POST api/persons
[HttpPost]
public Person Post([FromBody]Person person)
{if (person == null) return new Person();return new Person { Id = person.Id, Name = person.Name };
}// PUT api/persons/5
[HttpPut]
public string Put([FromBody]int id)
{return $"put {id}";
}// DELETE api/persons/5
[HttpDelete("{id}")]
public string Delete(int id)
{return $"del {id}";
}

Refit的使用

先通过Nuget安装Refit的包。

然后就是定义我们的interface了

public interface IPersonsApi
{[Get("/api/persons")]Task<List<Person>> GetPersonsAsync();[Get("/api/persons/{id}")]Task<Person> GetPersonAsync([AliasAs("id")]int personId);[Post("/api/persons")]Task<Person> AddPersonAsync([Body]Person person);[Put("/api/persons")]Task<string> EditPersonAsync([Body]int id);[Delete("/api/persons/{id}")]Task<string> DeletePersonAsync(int id);
}

来看看这个interface里面涉及到的部分内容。

  1. Get,Post等特性就表明了接口的请求方式,后面的值就是请求的相对路径。
  2. 相对路径中,可以使用占位符,来动态更新参数值。
  3. 如果方法名和请求参数名不一致,需要用AliasAs指明。
  4. 通过Body特性声明一个对象作为请求体发送到服务器
  5. 返回值定义是Task或者IObservable

然后是配合HttpClientFactory

再通过Nuget安装一下Refit.HttpClientFactory

如果PersonApi是注册到Euerka的,可以再添加Steeltoe的引用。

public void ConfigureServices(IServiceCollection services)
{services.AddRefitClient<IPersonsApi>().ConfigureHttpClient(options =>{options.BaseAddress = new Uri(Configuration.GetValue<string>("personapi_url"));//other settings of httpclient})//Steeltoe discovery//.AddHttpMessageHandler<DiscoveryHttpMessageHandler>();services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

前面在定义IPersonApi的时候,我们只指定了相对路径,而请求IP并没有指定,这里是放到ConfigureHttpClient里面去指定了。

同时根据不同环境,配置不同的appsettings.{env}.json,达到切换的效果。

同样的,如果想走服务发现,只需要放开注释的AddHttpMessageHandler,同时修改BaseeAddress为服务名的形式就可以了。

说了这么多,都还只是配置阶段,下面就来看看具体怎么用。

为了演示方便,就不在建一个Service层了,直接在控制器调用一下。

用法也很简单,直接在控制器注入一下就可以使用了。

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{private readonly IPersonsApi _api;public ValuesController(IPersonsApi api){this._api = api;}// GET api/values[HttpGet]public async Task<List<Person>> GetAsync(){return await _api.GetPersonsAsync();                             }// GET api/values/5[HttpGet("{id}")]public async Task<Person> Get(int id){return await _api.GetPersonAsync(id);}// POST api/values[HttpPost]public async Task<Person> Post([FromBody] Person value){return await _api.AddPersonAsync(value);}
}

到这里,代码层面的东西已经处理完了。

下面来看看使用Refit效果(这里只看两个Get请求的):

都是能正常拿到我们期望的结果。

最后再看看输出的日志,确认一下。

首先是访问/api/values

确确实实是向我们前面的PersonApi发起了请求。

然后是访问/api/values/5555

可见我们上面的别名(AliasAs)是起了效果的,能拼成正确的请求地址。

至于其他类型的请求,这里就不演示了,让大家自己去尝试一下吧。

总结

Refit用起来还是比较简单的,运行了一段时间也还表现正常!

当然本文介绍的也只是一些基本的用法!它还具有不错的扩展性,可以让我们根据自身需求做一些定制化的东西。

本文的示例代码RefitClientApi

转载于:https://www.cnblogs.com/catcher1994/p/9501387.html

Refit在ASP.NET Core中的实践相关推荐

  1. Refit 集成consul在asp.net core中的实践

    参考: https://aspdotnetcore.net/refit-consul/ Refit  WebApiClient  Feign等都是支持声名式的Restful服务调用的开源组件. 这个几 ...

  2. ASP.NET Core中的内存缓存

    ASP.NET Core中的内存中缓存 让我们看看如何通过缓存优化ASP.NET Core应用程序性能 我相信,在我们的工作中,每个人都收到来自客户的请求或来自我们应用程序用户的反馈,以提高响应速度. ...

  3. 【半译】在ASP.NET Core中创建内部使用作用域服务的Quartz.NET宿主服务

    在我的上一篇文章<在ASP.NET Core中创建基于Quartz.NET托管服务轻松实现作业调度>,我展示了如何使用ASP.NET Core创建Quartz.NET托管服务并使用它来按计 ...

  4. ASP.NET Core 中的依赖注入

    什么是依赖注入 软件设计原则中有一个依赖倒置原则(DIP),为了更好的解耦,讲究要依赖于抽象,不要依赖于具体.而控制反转(Ioc)就是这样的原则的其中一个实现思路, 这个思路的其中一种实现方式就是依赖 ...

  5. 【翻译】asp.net core中使用MediatR

    这篇文章来自:https://ardalis.com/using-mediatr-in-aspnet-core-apps 本文作为翻译,有一些单词翻译成中文可能会有一些误解(对于读者)或者错误(对于作 ...

  6. Hangfire在ASP.NET CORE中的简单实现

    hangfire是执行后台任务的利器,具体请看官网介绍:https://www.hangfire.io/ 新建一个asp.net core mvc 项目 引入nuget包 Hangfire.AspNe ...

  7. ASP.NET Core中的OWASP Top 10 十大风险-失效的访问控制与Session管理

    本博文翻译自: https://dotnetcoretutorials.com/2017/10/16/owasp-top-10-asp-net-core-broken-authentication-s ...

  8. ASP.NET Core 中文文档 第三章 原理(5)错误处理

    原文:Error Handling 作者:Steve Smith 翻译:谢炀(Kiler) 校对:高嵩(jack2gs).何镇汐 当你的ASP.NET应用发生错误的时候, 你可以采用本文所述的各种方法 ...

  9. ASP.NET Core 中 HttpContext 详解与使用 |

    ASP.NET Core 中 HttpContext 详解与使用 | Microsoft.AspNetCore.Http 详解 笔者没有学 ASP.NET,直接学 ASP.NET Core ,学完 A ...

最新文章

  1. 首批新冠肺炎人体疫苗来了!全球第一mRNA药物研发公司研制,已开启安全性临床试验...
  2. redis配置文件redis.conf参数说明
  3. grunt 打包前端代码
  4. Cache 工作原理、Cache 一致性,你想知道的都在这里
  5. Google、Azure、阿里云、RedHat…全球的 K8s 圈大佬聚在一起要聊啥?
  6. ios html5缩小,IOS H5页面图片点击捏合放大缩小
  7. pixhawk自学笔记之px4程序启动顺序
  8. python中列表字典和字符串的相互转化
  9. 机试指南第二章-经典入门-查找例题自解
  10. Linux下 查看网络连接状态的命令是,查看Linux操作系统下的网络连接状态命令
  11. 【转载】三角形测试用例
  12. Python:学习笔记(一)
  13. java如何使用live2d_关于live2D的使用
  14. java工程师linux命令大全
  15. VRay材质练习(一):水、玻璃、牛奶
  16. (SCI分区)查SCI期刊JCR分区的图解步骤
  17. 标准之争:影响 IPv6 部署的经济学因素
  18. Java- 求⼀个三位数,该三位数等与其每位数字的阶乘之和
  19. 机器学习—决策树模型
  20. multiwii 2.4配置中文注释

热门文章

  1. 留学生用ChatGPT写论文?真的会被开除!!!
  2. 【C语言】强制类型转换的原理
  3. 矩阵键盘扫描原理详解——单片机
  4. 用python代码将图片转换成字符
  5. paddlepaddle打比赛之高分辨率遥感影像建筑物变化检测
  6. c/c++,char型数组转化为int类型
  7. STM32笔记之 SDRAM
  8. 进制数制系统之间的转换
  9. 倾情奉献 绝色美男《青空下》漫画教程
  10. 发光二极管怎么接220v交流电