前言

本篇文章的内容是WebApiClient应用说明篇,如果你没有了解过WebApiClient,可以先阅读以下相关文章:

背景

随着Wcf、Webservice等的SOAP的份额越来越少,以及Restful Api的兴起,目前几乎所有新平台提供的接口,都只提供Restful Api,而.net平台下,没有类似Wcf这么简单的客户端可以直接请求和管理这些Restful api的解决方案,.net平台提供的HttpWebRequest、WebClient和HttpClient这三个类库,可用于实现Http接口的请求,但相比wcf得益于soap自我描述实现的自动生成客户端调用代码,Restful就没这么方便了,无论使用HttpWebRequest还是HttpClient,都需要对每个Api缩写沉长的调用代码。

使用WebApiClient

WebApiClient是在这样的背景下产生一款Http全异步的客户端库,它的出现,大幅度减轻了接口调用者的工作量,而且在调用Http接口上还非常容易维护和更新,还可以轻松应对设计不太友好的一些http接口。

使用WebApiClient,编程人员不再需要手动实现路径拼接、参数拼接、请求体组装和响应映射为模型这些繁琐的过程,以下为WebApiClient应用到项目中的一般流程:

1 声明http接口的Interface

[JsonReturn]
public interface IIotRemotePush : IDisposable
{
/// <summary>
/// 创建远程推送账号
/// </summary>
/// <param name="auth">授权</param>
/// <returns></returns>
[HttpPost("/v1/RemotePush/CreateAccount")]
ITask<ApiResult<PushAccount>> CreateAccountAsync(IotBasicAuth auth); /// <summary>
/// 获取推送服务信息
/// </summary>
/// <param name="id">pushId</param>
/// <returns></returns>
[HttpGet("/v1/Mqtt/GetPushSevice?id={id}")]
ITask<ApiResult<MqttService>> GetPushSeviceAsync(string id);
} /// <summary>
/// Api结果接口
/// </summary>
public interface IApiResult
{
/// <summary>
/// 错误码
/// </summary>
ErrorCode Code { get; set; } /// <summary>
/// 相关提示信息
/// </summary>
string Msg { get; set; }
} /// <summary>
/// 表示Api结果
/// </summary>
public class ApiResult<T> : IApiResult
{
/// <summary>
/// 错误码
/// </summary>
public ErrorCode Code { get; set; } /// <summary>
/// 相关提示信息
/// </summary>
public string Msg { get; set; } /// <summary>
/// 业务数据
/// </summary>
public T Data { get; set; }
}

2 调用http接口

WebApiClient不需要开者实现接口,使用HttpApiClient.Create方法可以动态创建接口的实现类的实例,调用实例的方法,就完成一个Api的请求。

using (var iotApi = HttpApiClient.Create<IIotRemotePush>())
{
var auth = new IotBasicAuth(config.AppId, config.AppToken);
var createResult = await iotApi.CreateAccountAsync(auth);
if (createResult.Code != ErrorCode.NoError)
{
return null;
} config.PushId = createResult.Data.Id;
config.PushToken = createResult.Data.Token;
await db.SaveChangesAsync(); return config;
}

3 异常定义与异常处理

在以上接口中,接口返回的都是ApiResult类型,此类型定义了一个ErrorCode类型的Code字段,这是业务的错误码,我们可以把它转换为.net的异常来处理。

/// <summary>
/// 表示Iot异常
/// </summary>
public class IotException : Exception
{
/// <summary>
/// 错误码
/// </summary>
public ErrorCode ErrorCode { get; private set; } /// <summary>
/// Iot异常
/// </summary>
/// <param name="apiResult">api结果值</param>
public IotException(IApiResult apiResult)
: base(apiResult.Msg)
{
this.ErrorCode = apiResult.Code;
}
}

我们还应该在Interface上扩展JsonResult,用于将ApiResult的ErrorCode转换为IotException,并抛出:

/// <summary>
/// 表示IotJson结果
/// </summary>
public class IotJsonResultAttribute : JsonReturnAttribute
{
protected override async Task<object> GetTaskResult(ApiActionContext context)
{
var apiResult = await base.GetTaskResult(context) as IApiResult;
if (apiResult != null && apiResult.Code != ErrorCode.NoError)
{
throw new IotException(apiResult);
}
return apiResult;
}
}

然后将新的IotJsonResultAttribute在Interface上替换JsonReturnAttribute:

[IotJsonResult]
public interface IIotRemotePush : IDisposable
{
...
}

最后,调用http接口的时候,可以使用Handle()扩展方法处理异常:

using (var iotApi = HttpApiClient.Create<IIotRemotePush>())
{
var auth = new IotBasicAuth(config.AppId, config.AppToken);
var createResult = await iotApi.CreateAccountAsync(auth)
.Handle()
.WhenCatch<IotException>(ex =>
{
// process exception
return default(ApiResult<PushAccount>);
})
.WhenCatch<Exception>(ex =>
{
// process exception
return default(ApiResult<PushAccount>);
}); if (createResult == null)
{
return null;
} config.PushId = createResult.Data.Id;
config.PushToken = createResult.Data.Token;
await db.SaveChangesAsync(); return config;
}

WebApiClient现状

WebApiClient项目目前已加入.NET China Foundation,正在为.net开源作出自己的一点贡献。

使用WebApiClient请求和管理Restful Api的更多相关文章

  1. Django后端项目----RESTful API

    一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...

  2. RESTful API 学习【第1篇】

    一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...

  3. 细说RESTful API之文档管理

    目录 API文档格式 文档管理方式 基于注解实现,代码和文档在一起 Swagger Api2Doc 基于API测试工具生成 Postman rest-client 独立编写文档 RAP DOCleve ...

  4. Django编写RESTful API(二):请求和响应

    欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我 ...

  5. HTTP请求封装:Ajax与RESTful API

    一.HTTP请求 HTTP即超文本传输协议,用以进行HTML 文件. 图片文件. 查询结果等的网络传输. 一个完整的HTTP请求包括:请求行.请求头.空行和请求数据(请求数据可以为空) HTTP1.1 ...

  6. 请求与上传文件,Session简介,Restful API,Nodemon

    作者 | Jeskson 来源 | 达达前端小酒馆 请求与上传文件 GET请求和POST请求 const express = require('express'); const app = expre ...

  7. httpclient连接池在ES Restful API请求中的应用

    package com.wm.utils; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http ...

  8. 使用Flask设计带认证token的RESTful API接口[翻译]

    上一篇文章, 使用python的Flask实现一个RESTful API服务器端  简单地演示了Flask实的现的api服务器,里面提到了因为无状态的原则,没有session cookies,如果访问 ...

  9. RESTful API 设计最佳实践

    背景 目前互联网上充斥着大量的关于RESTful API(为了方便,以后API和RESTful API 一个意思)如何设计的文章,然而却没有一个"万能"的设计标准:如何鉴权?API ...

随机推荐

  1. java中队列Queue的使用

    1.在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.Queue接口与List.Set同一级别,都是继承了Collection接口.Queue使用时要尽量避免Colle ...

  2. CTSC 2017 滚粗记

    CTSC 2017 滚粗记 结束好几天了一直没写. 明天就要去参加二轮省选了,填一下坑吧. 所以可能很多东西已经忘了 Day -2 [5.5 Fri] 周五晚上是其他学信竞的同学来机房的时间... 也 ...

  3. win7下MySQL的安装配置及卸载 笔记分享

    一.官网下载地址:https://dev.mysql.com/downloads/mysql/ 1.选择对应版本,下载免安装版: 2.不要注册账号,点击"No thanks,just sta ...

  4. ES6 学习笔记之二 块作用域与闭包

    "闭包是函数和声明该函数的词法环境的组合." 这是MDN上对闭包的定义. <JavaScript高级程序设计>中则是这样定义的:闭包是指有权访问另一个函数作用域中的变量 ...

  5. shell编程之运算符(3)

    declare声明变量类型 declare[+/-][选项]变量名 选项: - : 给变量设定类型属性 + : 取消变量的类型属性 -a : 将变量声明为数组型 -i : 将变量声明为整数型(inte ...

  6. PHPStorm 常用 设置配置 和快捷键大全 Win/Mac

    [转自 http://blog.csdn.net/fenglailea/article/details/53350080] PHPStorm 下载及主题样式下载 http://www.lanmps.c ...

  7. 基于agenda的Nodejs定时任务管理框架搭建

    0.背景 在大型项目中,定时任务的应用场景越来越广.一般来说,按照微服务的思想,我们会将定时任务单独部署一套服务,核心的业务接口独立到另一个服务中,从而降低相互之间的耦合程度.在需要使用定时任务时,只 ...

  8. ErrorKiller:Failed to decode response: zlib_decode(): data error

    先更新composer自己,composer self-update 然后再更新依赖关系 composer update

  9. 剑指offer第六天

    29.最小的K个数 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 解法一: Partition思想 允许改变原始数组的情况, ...

  10. hihoCoder 树结构判定(并查集)

    思路:树满足两个条件: 1.顶点数等于边数加一 2.所有的顶点在一个联通块 那么直接dfs或者并查集就可以了. AC代码 #include <stdio.h> #include<st ...