HTTP请求组件 BrokerClient

BrokerClient主要用于支持各类Http请求

如何引入

功能包含在Aegis.Net.Broker的Nuget包中,当前最新版本是1.0.7-preview1

BrokerClient不需要使用任何配置

快速使用

使用BrokerClient前,首先需要定义调用Http服务的契约接口

比如这个例子,定义了HIS下调用医生站的契约接口

public interface IDoctorContract
{
    [Post("/api/his-api/receiveHisUpdate")]
    public Task<BaseDto<string>> ReceiveHisUpdateAsync([Body] QuerWardBedTotalRequest request);

    [Post("/api/emr/get-patient-emr-pdf")]
    public Task<BaseDto<List<GetPatientEmrPdfDto>>> GetPatientEmrPdfAsync([Body] GetPatientEmrPdfRequest request);
}

定义好接口好,在具体需要调用的类中直接使用BrokerClient.Get就可以直接获取对应接口,在调用的时候直接使用契约接口调用方法即可。

 public class OpDoctorService : IBusinessService
{
    IDoctorContract _doctorContract;
    public OpDoctorService(ILogger<OpDoctorService> _logger, IApiLogsService apiLogsService)
    {
        _doctorContract = BrokerClient.Get<IDoctorContract>(ConfigManager.Get("OpDoctorURL"));
    }

    public async Task CallUpdate(QuerWardBedTotalRequest request)
    {
        var result = await _doctorContract.ReceiveHisUpdateAsync(request);
        ...
    }

}

请求相关

在定义具体契约接口时,可以使用各种Attribute来定义该接口的HTTP相关地址和方法信息。

路径

https://api.example.com/api/v1/users/getuser,这个路径可以拆分为三部分

  • Base Address 基础地址,常用于域名,IP地址等。一般使用配置读取,在这里是 https://api.example.com
  • Base Path 基础路径,用于相对固定路由路径。这里是 api/v1/users
  • Method Path 方法路径,标注具体方法。这里是 getuser

Base Address 基础地址

设置接口的基础地址有两种方案

  1. 在接口最上方使用[BaseAddress(...)],不推荐该方案,一般基础地址都是从配置或数据中读取的
  2. 使用BrokerClient.Get<T>(...)new BrokerClient(...)推荐使用这种方式,就像快速使用的例子,BrokerClient.Get<IDoctorContract>(ConfigManager.Get("OpDoctorURL"))一样。

Base Path 基础路径

可以设置在接口上标注某个领域或者固定的基础路径,如下面的例子

[BasePath("api/v1/users")]
public interface IUserContract

Method Path 方法路径

用于设置具体的方法路径

[BasePath("api/v1/users")]
public interface IUserContract
{
    [Post("getuser")]
    public Task<List<User>> GetUsers([Body]UserRequest request);
}

可以在接口上直接定义该接口的请求,支持各类HTTP方法,比如 [Get("path")][Post("path")]等。

返回类型

目前契约接口只支持异步调用,所以所有的返回类型都带有Task 返回的数据类型,一共有以下几种类型:

  • Task 无返回值结果
  • Task<T> 指定泛型返回值
  • Task<string> 返回string类型的结果消息
  • Task<HttpResponseMessage> 返回HttpResponseMessage,具体参考微软文档
  • Task<Response<T>> 返回包含返回HttpResponseMessage和指定泛型返回值的结果
  • Task<Stream> 返回包含流的结果,主要用于下载文件

指定泛型返回值的结果会默认使用Json序列化器返回。

[BasePath("api/v1/users")]
public interface IUserContract
{
    //添加用户,不需要验证是否成功
    [Post("adduser")]
    public Task AddUser([Body]AddUserRequest request); //无返回值

    //获取用户列表
    [Post("getuser")]
    public Task<List<User>> GetUsers([Body]UserRequest request); //指定泛型返回值

    //获取用户说明的XML对象,使用字符串查询后续用XML序列器序列化
    [Get("getuserdescription")]
    public Task<string> GetUserDescription([Query]UserRequest request);

    //更新用户信息,因为调了第三方接口可能会失败,所以获取HttpResponseMessage的原始内容来判断是否异常
    [Post("changeuserstate")]
    public Task<HttpResponseMessage> ChangeUserState([Body]UserRequest request);

    //更新用户,可以用结果直接GetContent()来获取泛型结果,也可以用Response里的message来验证是否异常
    [Post("updateuser")]
    public Task<Response<User>> UpdateUser([Body]UserRequest request);

    //下载文件
    [Post("download")]
    public Task<Stream> Download([Body]UserFilterRequest request);
}

在日常请求中,经常需要带各种类型的Header,无论是固定的header,还是用于验证的header,Broker为header设置提供了较为便利的方式。

固定Header设置

定义在接口上

[Header("X-Source", "His")]
[Header("Cache-Control", "no-cache")]
public interface IUserContract
{
    [Get("users")]
    Task<List<User>> GetUsersAsync();
}

定义在方法上

[Header("Cache-Control", "no-cache")]
public interface IUserContract
{
    [Header("X-Source", "His")]
    [Get("users")]
    Task<List<User>> GetUsersAsync();
}

可变Header设置

一般用于传AuthorizationToken之类的可变Header头

定义在接口属性上,所有该接口下的方法请求出去时都会将该属性带在header上。

public interface IUserContract
{
    [Header("Authorization")]
    string Authorization { get; set; }

    [Get("users")]
    Task<List<User>> GetUsersAsync();
}

定义在方法参数上,在调用该方法时传入具体数据

public interface IUserContract
{
    [Get("users")]
    Task<List<User>> GetUsersAsync([Header("Authorization")] string authorization);
}

Header优先级

当接口Attribute、属性和方法参数上都包含同名Header时,并都设置了值。这时候的Header优先级是 方法参数 > 接口属性 > 接口Attribute,最终会使用方法参数的值请求出去。

[Header("Authorization","1")]
public interface IUserContract
{
    [Header("Authorization")]
    string Authorization { get; set; }

    [Get("users")]
    Task<List<User>> GetUsersAsync([Header("Authorization")] string authorization);
}

方法参数设置

支持所有类型的参数设置,参照下列代码:

public interface IUserContract
{
    //GetUser?userId=xx&age=18
    [Get("user")]
    Task<List<User>> GetUserAsync([Query]string userId,[Query]string age);

    //GetUsers,参数带在raw body中的json
    [Post("getusers")]
    Task<List<User>> GetUsers([Body]UserRequest request);

    //添加用户的表单式提交,(也就是类型为application/x-www-form-urlencoded的请求)
    [Post("adduser")]
    Task<List<User>> AddUser([Body(BodySerializationMethod.UrlEncoded)]Dictionary<string,object> request);

    //Url重写类型的请求,把参数定义在Path中
    [Get("users/{userId}")]
    Task<User> GetUserAsync([Path] string userId);

    //上传文件,使用流作为Body即可
    [Header("Content-Disposition", "form-data; filename=\"somefile.txt\"")] //这里填文件名
    [Header("Content-Type", "text/plain")] //定义具体的媒体类型
    [Post("upload")]
    Task UploadFile([Body] Stream file);
}

需要注意的是BodySerializationMethod.UrlEncoded的表单式提交只支持使用IDictionaryDictionary提交数据。

results matching ""

    No results matching ""