Norns.Urd.HttpClient

Norns.Urd.HttpClient 基于AOP框架 Norns.Urd实现,

是对 System.Net.Http下的 HttpClient封装,让大家只需简单在接口定义就可以实现http的调用,可以减少一些重复代码的书写。

可以和已有的 Norns.Urd.Extensions.Polly 以及 Norns.Urd.Caching.Memory 配合使用。

源码放在:https://github.com/fs7744/Norns.Urd

如何启用 HttpClient 功能

  1. 引入Norns.Urd.HttpClient
dotnet add package Norns.Urd.HttpClient
  1. 代码中开启 HttpClient 功能,只需
new ServiceCollection()
.ConfigureAop(i => i.EnableHttpClient())
  1. 定义 要使用的 HttpClient 接口

举例如:

[BaseAddress("http://localhost.:5000")]
public interface ITestClient
{
[Get("WeatherForecast/file")]
[AcceptOctetStream]
Task<Stream> DownloadAsync(); [Post("WeatherForecast/file")]
[OctetStreamContentType]
Task UpoladAsync([Body]Stream f);
}
  1. 注册到 ioc 中
new ServiceCollection()
.AddSingleton<ITestClient>() // 按照自己需要设置生命周期就好,并且不需要写具体实现,Norns.Urd.HttpClient会为您生成对应IL代码
.ConfigureAop(i => i.EnableHttpClient())
  1. 通过DI 使用就好, 比如
[ApiController]
[Route("[controller]")]
public class ClientController : ControllerBase
{
private readonly ITestClient client; public ClientController(ITestClient client)
{
this.client = client;
} [HttpGet("download")]
public async Task<object> DownloadAsync()
{
using var r = new StreamReader(await client.DownloadAsync());
return await r.ReadToEndAsync();
}
}

HttpClient支持的功能

Url 配置

BaseAddress

如果有些网站域名或者基础api地址都是很多接口都会使用的,就可以在接口上使用 BaseAddressAttribute

如:

[BaseAddress("http://localhost.:5000")]
public interface ITestClient
各种 Http Method 支持设置Url

Http Method 支持如下:

  • GetAttribute
  • PostAttribute
  • PutAttribute
  • DeleteAttribute
  • PatchAttribute
  • OptionsAttribute
  • HeadAttribute

(上述method 不够使用时,可以继承HttpMethodAttribute 自定义实现)

所有的这些Http Method都支持配置Url,有以下两种方式支持:

  • 静态配置
[Post("http://localhost.:5000/money/getData/")]
public Data GetData()
  • 动态配置

默认支持从 IConfiguration 通过key获取 url 配置

[Post("configKey", IsDynamicPath = true)]
public Data GetData()

如果这样简单的配置形式不支持您的需求,可以实现 IHttpRequestDynamicPathFactory 接口替换配置实现方式,实现好的类只需注册到IOC容器就可以了。

实现示例可以参考 ConfigurationDynamicPathFactory

路由参数设置

如果某些url 路由参数需要动态设置,您可以通过RouteAttribute设置, 如

[Post("getData/{id}")]
public Data GetData([Route]string id)

如果参数名字不匹配url里面的设置,可以通过Alias = 设置,如

[Post("getData/{id}")]
public Data GetData([Route(Alias = "id")]string number)
Query string 设置

Query string参数可以在方法参数列表中设置

[Post("getData")]
public Data GetData([Query]string id);
//or
[Post("getData")]
public Data GetData([Query(Alias = "id")]string number);

其Url结果都为 getData?id=xxx,

参数类型支持基本类型和 class,

当为class 时,会取class的属性作为参数,

所以当属性名不匹配定义时,可以在属性上用 [Query(Alias = "xxx")]指定

Request body 设置

Request body 可以通过可以在方法参数列表中设置BodyAttribute指定参数,

需注意,只有第一个有BodyAttribute的参数会生效, 举例如

public void SetData([Body]Data data);

将根据设置的 Request Content-Type 选择序列化器序列化body

Response body 设置

Response body 的类型指定,只需在方法的 return type 写上需要的类型就好,支持以下

  • void (忽略反序列化)
  • Task (忽略反序列化)
  • ValueTask (忽略反序列化)
  • T
  • Task
  • ValueTask
  • HttpResponseMessage
  • Stream (只能Content-Type为 application/octet-stream 时起效)

举例如:

public Data GetData();

Content-Type 设置

无论 Request 还是 Response 的 Content-Type 都会影响 序列化和反序列化器的选择,

默认支持json/xml的序列化和反序列化,可以通过如下设置

  • JsonContentTypeAttribute
  • XmlContentTypeAttribute
  • OctetStreamContentTypeAttribute

举例如:

[OctetStreamContentType]
public Data GetData([Body]Stream s);

对应的Accept 设置为

  • AcceptJsonAttribute
  • AcceptXmlAttribute
  • AcceptOctetStreamAttribute

举例如:

[AcceptOctetStream]
public Stream GetData();

json 序列化器默认为 System.Text.Json

更换json 序列化器为 NewtonsoftJson

  1. 引入 Norns.Urd.HttpClient.NewtonsoftJson
  2. 在 ioc 注册方法, 如
new ServiceCollection().AddHttpClientNewtonsoftJosn()

自定义序列化器

当现有序列化器不足以支持需求时,

只需实现 IHttpContentSerializer 并向 ioc 容器注册即可

自定义 Header

除了上述已经提到的header之外,还可以通过添加其他header

同样有以下两种方式:

  • 使用HeaderAttribute在接口或方法静态配置
[Header("x-data", "money")]
public interface ITestClient {}
//or
[Header("x-data", "money")]
public Data GetData();
  • 方法参数动态配置
public Data GetData([SetRequestHeader("x-data")]string header);

自定义HttpRequestMessageSettingsAttribute

当现有HttpRequestMessageSettingsAttribute不足以支持需求时,

只需继承 HttpRequestMessageSettingsAttribute 实现自己的功能,

在对应的接口/方法使用即可

通过参数设置获取 Response Header

当有时我们需要获取 response 返回的 header 时,

我们可以 out 参数 + OutResponseHeaderAttribute 获取 Response Header的值

(需注意, 只有同步方法, out参数才能起作用)

举例如:

public Data GetData([OutResponseHeader("x-data")] out string header);

HttpClient 一些参数设置方法

MaxResponseContentBufferSize
[MaxResponseContentBufferSize(20480)]
public interface ITestClient {}
//or
[MaxResponseContentBufferSize(20480)]
public Data GetData()
Timeout
[Timeout("00:03:00")]
public interface ITestClient {}
//or
[Timeout("00:03:00")]
public Data GetData()
ClientName

当需要结合 HttpClientFactory 获取特殊设置的 HttpClient 时,可以通过ClientNameAttribute 指定

[ClientName("MyClient")]
public interface ITestClient {}
//or
[ClientName("MyClient")]
public Data GetData()

就可以获取到这样指定的HttpClient

services.AddHttpClient("MyClient", i => i.MaxResponseContentBufferSize = 204800);
HttpCompletionOption

HttpClient 调用时的 CompletionOption 参数同样可以设置

HttpCompletionOption.ResponseHeadersRead 是默认配置

[HttpCompletionOption(HttpCompletionOption.ResponseContentRead)]
public interface ITestClient {}
//or
[HttpCompletionOption(HttpCompletionOption.ResponseContentRead)]
public Data GetData()

全局 HttpRequestMessage 和 HttpResponseMessage 处理

如果需要全局对 HttpRequestMessage 和 HttpResponseMessage 做一些处理,比如:

  • 链路追踪id 设置
  • response 异常自定义处理

可以通过实现IHttpClientHandler并向ioc 容器注册使用

举例默认的 status code 检查 ,如:

public class EnsureSuccessStatusCodeHandler : IHttpClientHandler
{
public int Order => 0; public Task SetRequestAsync(HttpRequestMessage message, AspectContext context, CancellationToken token)
{
return Task.CompletedTask;
} public Task SetResponseAsync(HttpResponseMessage resp, AspectContext context, CancellationToken token)
{
resp.EnsureSuccessStatusCode();
return Task.CompletedTask;
}
}

当然,如果该 StatusCode 检查处理不需要的话,可以直接在ioc 容器清除掉, 如:

services.RemoveAll<IHttpClientHandler>();
// 然后添加自己的处理
services.AddSingleton<IHttpClientHandler, xxx>();

有任何问题欢迎大家提issue (_)

介绍一个新库: Norns.Urd.HttpClient的更多相关文章

  1. 介绍一个golang库:fastcache

    学习VictoriaMetrics源码的时候发现,VictoriaMetrics的缓存部分,使用了同一产品下的fastcache.下面分享阅读fastcache源码的的结论: 1.官方介绍 fastc ...

  2. MSSQL-Scripter,一个新的生成T-SQL脚本的SQL Server命令行工具

    这里向大家介绍一个新的生成T-SQL脚本的SQL Server命令行工具:mssql-scripter.它支持在SQL Server.Azure SQL DB以及Azure SQL DW中为数据库生成 ...

  3. 介绍一个python视频处理库:moviepy

    由于博客园的插件和我自己博客的插件不一致,代码以及视频插入转换很麻烦,所以还是我原来博客的地址查看吧. 介绍一个python视频处理库:moviepy

  4. 使用source创建一个新项目(将本地项目文件和github远程库链接)

    1. 本地创建项目文件夹 2. 将本地的项目添加到source中(我使用的source版本为2.4.7.0) 3. github创建远程库  4. 关联本地项目文件和github库 确定添加就可以了. ...

  5. Git库搭建好之后,当要提交一个新的文件,需要做的是3个步骤

    Git库搭建好之后,当要提交一个新的文件,需要做的是3个步骤 1.git add new.txt 2.git commit -m "add a new file" 3.git pu ...

  6. 【Hades】ades是一个开源库,基于JPA和Spring构建,通过减少开发工作量显著的改进了数据访问层的实现

    几乎每个应用系统都需要通过访问数据来完成工作.要想使用领域设计方法,你就需要为实体类定义和构建资源库来实现领域对象的持久化.目前开发人员经常使用JPA来实现持久化库.JPA让持久化变得非常容易,但是仍 ...

  7. GitHub 常用命令使用介绍(新同学入门)

    经济在不断发展,社会在不断进步,以往的互联网在现在看来都可以称为传统互联网了,因为技术不断的在突破和革新. 本文主要介绍一下版本管理工具,我猜测很多人还是用SVN.CVS或者Resion,但是,今天我 ...

  8. 教你一步步发布一个开源库到 JCenter

    今天想来分享下,如何一步步自己发布一个开源库到 JCenter 这方面的博客网上已经特别多了,所以本篇并不打算仅仅只是记录流程步骤而已,而是尽可能讲清楚,为什么需要有这个步骤,让大伙知其然的同时还知其 ...

  9. 你不需要 jQuery,但你需要一个 DOM 库

    写这篇文章的目的,一方面是介绍一下自己编写的模块化 DOM 库 domq.js,另一方面是希望大家对 jQuery 有一个正确的认识,即使 jQuery 已经逐渐退出历史舞台,但是它的 API 将会以 ...

随机推荐

  1. python核心高级学习总结5--------python实现线程

    在代码实现上,线程的实现与进程的实现很类似,创建对象的格式都差不多,然后执行的时候都是用到start()方法,与进程的区别是进程是资源分配和调度的基本单位,而线程是CPU调度和分派的基本单位.其中多线 ...

  2. 第11.27节 Python正则小结:正则静,静则明,明则虚,虚则无为而无不为也

    正则表达式的章节到此就结束了,老猿现在觉得对我们这些身具程序猿基因特色的人来说,正则表达式应该是蛮可口的开胃小菜. 在写标题时,本来想写"正则表达式小结",后来想了想,百度了一下, ...

  3. HBase的基本使用(安装配置、启动关闭、hbash shell的基本操作、phoenix、实战)

    HBase的前提条件: JDK SSH Hadoop JDK:Hadoop和JDK运行的环境,他们的守护进程运行在JVM下.HBase支持JDK 1.6以上的版本.比如: jdk-8u161-linu ...

  4. 微软面试题:剑指 Offer 51. 数组中的逆序对 Hard 出现次数:3

    题目描述: 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对. 输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出: 5 限制: ...

  5. 微信小程序云开发如何上手

    简要介绍 微信小程序云开发,是基于 Serverless 的一站式后端云服务,涵盖函数.数据库.存储.CDN等服务,免后端运维.基于云开发可以免鉴权调用微信所有开放能力. 前提准备 微信开发者工具 创 ...

  6. Linux下修改禅道端自定义端口号

    第一种方式 一.        首先,如果我们的服务器的80端口没有开放的话,那么我们就是只能修改Apache应用服务的端口了,其实非常简单,安装完成禅道后,在任意目录下输入命令: /opt/zbox ...

  7. ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes

    这个错误是我在安装ambari平台时,准备为ambari指定mysql数据库时,执行建表语句时遇到的. ERROR 1071 (42000): Specified key was too long; ...

  8. 精尽Spring MVC源码分析 - HandlerMapping 组件(四)之 AbstractUrlHandlerMapping

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  9. [OI笔记]基础图论/图算法

    [2017.8.29 00:00]--前几天开始好好学了几天的图论,不过这最近又突然因为一些原因(其实是晚上没睡好导致白天没精神)颓废了几天-一方面为了控制自己同时也可以当做之后noip前复习用的笔记 ...

  10. 深度学习炼丹术 —— Taoye不讲码德,又水文了,居然写感知器这么简单的内容

    手撕机器学习系列文章就暂时更新到此吧,目前已经完成了支持向量机SVM.决策树.KNN.贝叶斯.线性回归.Logistic回归,其他算法还请允许Taoye在这里先赊个账,后期有机会有时间再给大家补上. ...