使用WebApiClient请求和管理Restful Api
前言
本篇文章的内容是WebApiClient应用说明篇,如果你没有了解过WebApiClient,可以先阅读以下相关文章:
- WebApi client 的面向切面编程
- 我来给.Net设计一款HttpClient
- .Net45下HttpClient的几个缺陷
- .net的retrofit--WebApiClient库
- .net的retrofit--WebApiClient库深入篇
- .net的retrofit--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的更多相关文章
- Django后端项目----RESTful API
一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...
- RESTful API 学习【第1篇】
一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...
- 细说RESTful API之文档管理
目录 API文档格式 文档管理方式 基于注解实现,代码和文档在一起 Swagger Api2Doc 基于API测试工具生成 Postman rest-client 独立编写文档 RAP DOCleve ...
- Django编写RESTful API(二):请求和响应
欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我 ...
- HTTP请求封装:Ajax与RESTful API
一.HTTP请求 HTTP即超文本传输协议,用以进行HTML 文件. 图片文件. 查询结果等的网络传输. 一个完整的HTTP请求包括:请求行.请求头.空行和请求数据(请求数据可以为空) HTTP1.1 ...
- 请求与上传文件,Session简介,Restful API,Nodemon
作者 | Jeskson 来源 | 达达前端小酒馆 请求与上传文件 GET请求和POST请求 const express = require('express'); const app = expre ...
- httpclient连接池在ES Restful API请求中的应用
package com.wm.utils; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http ...
- 使用Flask设计带认证token的RESTful API接口[翻译]
上一篇文章, 使用python的Flask实现一个RESTful API服务器端 简单地演示了Flask实的现的api服务器,里面提到了因为无状态的原则,没有session cookies,如果访问 ...
- RESTful API 设计最佳实践
背景 目前互联网上充斥着大量的关于RESTful API(为了方便,以后API和RESTful API 一个意思)如何设计的文章,然而却没有一个"万能"的设计标准:如何鉴权?API ...
随机推荐
- 洛谷 [P2774] 方格取数问题
二分图最大点权独立集 通过题目描述我们可以很明显的看出要通过二分图建模,二分图求最大独立点集很容易,就是建立二分图求n-最小割,然而这里加入了权值,而且权值是在点上的,那么我们对于每个点连一条到源点或 ...
- BZOJ 4537: [Hnoi2016]最小公倍数 [偏序关系 分块]
4537: [Hnoi2016]最小公倍数 题意:一张边权无向图,多组询问u和v之间有没有一条a最大为a',b最大为b'的路径(不一定是简单路径) 首先想到暴力做法,题目要求就是判断u和v连通,并查集 ...
- NOIP2016提高组初赛(C++语言)试题 个人的胡乱分析 Part 2.
洛谷秋令营day1模拟赛原地爆炸,心态崩了.于是打算写一下初赛题放松一下. 上次胡乱分析到了选择题,这次我想说说后面的题. 问题求解 T1.有一个1x8的方格图形,黑白两色填涂每个方格,两个黑格并不能 ...
- BZOJ 3505: [Cqoi2014]数三角形 [组合计数]
3505: [Cqoi2014]数三角形 给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个. 注意三角形的三点不能共线. 1<=m,n<=1000 $n++ m++$ $ans ...
- URL中特殊符号的处理
问题描述 我们在对接第三方系统的时候通常需要get或post来传输数据,但此时如果参数中存在&% #*!包括空格等特殊符号的时候就无法正常请求具体表现在参数获取不正确或者获取不到参数,甚至有时 ...
- 阿里云学习之API网关
注:此处仅供api的创建做一个补充参考,API网关的优缺点及创建过程中的参数详情,请参考阿里云开放文档:https://helpcdn.aliyun.com/document_detail/29478 ...
- apache服务器绑定泛解析域名
<VirtualHost *:80> DocumentRoot "E:\web\bubuchu" ServerName bubuchu.com ServerAlias ...
- CSS中可以继承和不可继承的常见属性
一.无继承性的属性 1.display:规定元素应该生成的框的类型 2.文本属性: vertical-align:垂直文本对齐 text-decoration:规定添加到文本的装饰 text-shad ...
- POI导出EXCEL,浏览器不兼容,文件名称乱码,文件无法打开解决方法
- Java经典编程题50道之三十七
有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位. public class Example37 { public static v ...