声明式RESTful客户端在asp.net core中的应用
1 声明式RESTful客户端
声明式服务调用的客户端,常见有安卓的Retrofit、SpringCloud的Feign等,.net有Refit和WebApiClient,这些客户端都是以java或.net某个语言来声明接口,描述如何请求RESTful api。
1.1 WebApiClient
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()时,在新的程序集创建了TInterface的代理类,类名与TInterface相同,命名空间也相同,由于代理类和TInterface接口不在同一程序集,所以要求TInterface为public。
- 可以在项目中直接引用WebApiClient.JIT.dll就能使用;
- 不适用于不支持JIT技术的平台(IOS、UWP);
- 接口要求为public;
WebApiClient.AOT
在编译过程中使用Mono.Cecil修改编译得到的程序集,向其插入Http请求接口的代理类IL指令,这一步是在AOT编译阶段之前完成。代理类型所在的程序集、模块、命名空间与接口类型的一样,其名称为$前缀的接口类型名称,使用反编译工具查看项目编译后的程序集可以看到这些代理类。
- 项目必须使用nuget安装WebApiClient.AOT才能正常使用;
- 没有JIT,支持的平台广泛;
- 接口不要求为public,可以嵌套在类里面;
1.2 Refit
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.Extensions项目简单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。
声明式RESTful客户端在asp.net core中的应用的更多相关文章
- net core天马行空系列-微服务篇:全声明式http客户端feign快速接入微服务中心nacos
1.前言 hi,大家好,我是三合,距离上一篇博客已经过去了整整两年,这两年里,博主通关了<人生>这个游戏里的两大关卡,买房和结婚.最近闲了下来,那么当然要继续写博客了,今天这篇博客的主要内 ...
- spring cloud 声明式rest客户端feign调用远程http服务
在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.Feign就是Spring Cloud提供的一种声明式R ...
- C#调用接口注意要点 socket,模拟服务器、客户端通信 在ASP.NET Core中构建路由的5种方法
C#调用接口注意要点 在用C#调用接口的时候,遇到需要通过调用登录接口才能调用其他的接口,因为在其他的接口需要在登录的状态下保存Cookie值才能有权限调用, 所以首先需要通过调用登录接口来保存c ...
- 3.【Spring Cloud Alibaba】声明式HTTP客户端-Feign
使用Feign实现远程HTTP调用 什么是Feign Feign是Netflix开源的声明式HTTP客户端 GitHub地址:https://github.com/openfeign/feign 实现 ...
- Spring Cloud 入门教程(六): 用声明式REST客户端Feign调用远端HTTP服务
首先简单解释一下什么是声明式实现? 要做一件事, 需要知道三个要素,where, what, how.即在哪里( where)用什么办法(how)做什么(what).什么时候做(when)我们纳入ho ...
- Spring Cloud官方文档中文版-声明式Rest客户端:Feign
官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http ...
- Taurus.MVC 微服务框架 入门开发教程:项目集成:2、客户端:ASP.NET Core(C#)项目集成:应用中心。
系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...
- 声明式HTTP客户端-Feign 使用入门详解
什么是 OpenFeign OpenFeign (以下统一简称为 Feign) 是 Netflix 开源的声明式 HTTP 客户端,集成了 Ribbon 的负载均衡.轮询算法和 RestTemplat ...
- ASP.NET Core中使用GraphQL - 第一章 Hello World
前言 你是否已经厌倦了REST风格的API? 让我们来聊一下GraphQL. GraphQL提供了一种声明式的方式从服务器拉取数据.你可以从GraphQL官网中了解到GraphQL的所有优点.在这一系 ...
随机推荐
- []T 还是 []*T, 这是一个问题
全面分析Go语言中的类型和类型指针的抉择 目录 [−] 副本的创建 T的副本创建 *T的副本创建 如何选择 T 和 *T 什么时候发生副本创建 最常见的case map.slice和数组 for-ra ...
- YAML基础教程
一.YAML介绍YAML参考了其他多种语言,包括:XML.C语言.Python.Perl以及电子邮件格式RFC2822.Clark Evans在2001年5月在首次发表了这种语言,另外Ingy döt ...
- python书籍推荐:python编码推荐(高清完整pdf)
目录INF-qa Python 编码规范................................................................................ ...
- 七牛云免费对象存储,并绑定到cloudreve中
之前开通了腾讯云的对象存储COS并使用中,不过之前主要将它当作云盘使用,这两天再做博客系统时发现也可以将它作为网站的图库,这样对网站的访问效率也会提高. 今天了解到七牛云有免费的对象存储可以使用,于是 ...
- 版本号对比 -- Python实现
相同位数版本号大小比较: def abc(str1, str2): if str1 == "" or str2 == "": print("输入包含空 ...
- C#语言介绍
C#(读作“See Sharp”)是一种简单易用的新式编程语言,不仅面向对象,还类型安全. C# 源于 C 语言系列,C.C++.Java 和 JavaScript 程序员很快就可以上手使用. C# ...
- css3 之炫酷的loading效果
css3 之炫酷的loading效果 今天实现了一个炫酷的loading效果,基本全用css来实现,主要练习一下css3的熟练运用 js需要引入jquery 只用到了一点点js 先看效果图 html: ...
- 18 章 CSS 链接、光标、 DHTML 、缩放
1.CSS 中链接的使用 2.CSS 中光标的使用 3.CSS 中 DHTML 的使用 4.CSS 中缩放的使用 1 18 8. .1 1 S CSS 中 链接的使用 超链接伪类属性 a:link ...
- Git:三、工作原理
首先,我们对工作区也就是文件夹中的文档进行修改. 然后,把修改并需要存档的文档用add命令放到暂存区,并且可以放很多文档. 最后,一个阶段的工作告一段落,使用commit命令把暂存区的内容一股脑存到G ...
- PHP Socket编程(转)
[PHPsocket编程专题(理论篇)]初步理解TCP/IP.Http.Socket.md [PHPsocket编程专题(实战篇①)]php-socket通信演示 [PHPsocket编程专题(实战篇 ...