介绍一个新库: Norns.Urd.HttpClient

Norns.Urd.HttpClient

Norns.Urd.HttpClient 基于AOP框架 Norns.Urd实现,
是对 System.Net.Http下的 HttpClient封装,让你们只需简单在接口定义就能够实现http的调用,能够减小一些重复代码的书写。
能够和已有的 Norns.Urd.Extensions.Polly 以及 Norns.Urd.Caching.Memory 配合使用。git

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

如何启用 HttpClient 功能

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

举例如:json

[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地址都是不少接口都会使用的,就能够在接口上使用 BaseAddressAttributeapi

如:app

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

Http Method 支持以下:框架

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

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

全部的这些Http Method都支持配置Url,有如下两种方式支持:网站

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

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

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

若是这样简单的配置形式不支持您的需求,能够实现 IHttpRequestDynamicPathFactory 接口替换配置实现方式,实现好的类只需注册到IOC容器就能够了。
实现示例能够参考 ConfigurationDynamicPathFactoryurl

路由参数设置

若是某些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 (_)

相关文章
相关标签/搜索