介紹一個新庫: 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 (_)

相關文章
相關標籤/搜索