使用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 ...
随机推荐
- SSD trim及4k对齐
trim可以帮助减小SSD的写放大WA问题,删除文件后不仅仅是将文件标记为删除,而是在SSD空闲的时候统一进行删除. Linux下的trim支持叫discard,修改fstab文件,在挂载参数中加上d ...
- CTP期货期权交易开发
CTP交易部分接口说明 综合交易平台(Comprehensive Transaction Platform,CTP)是专门为期货公司开发的一套期货经纪业务管理系统,由交易.风险控制和结算三大系统组成. ...
- [转载]完全版线段树 by notonlysuccess大牛
原文出处:http://www.notonlysuccess.com/ (好像现在这个博客已经挂掉了,在网上找到的全部都是转载) 今天在清北学堂听课,听到了一些很令人吃惊的消息.至于这消息具体是啥,等 ...
- bzoj 4827: [Hnoi2017]礼物 [fft]
4827: [Hnoi2017]礼物 题意:略 以前做的了 化一化式子就是一个卷积和一些常数项 我记着确定调整值还要求一下导... #include <iostream> #include ...
- BZOJ 1856: [Scoi2010]字符串 [Catalan数]
1856: [Scoi2010]字符串 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1418 Solved: 790[Submit][Status][ ...
- Git点滴记录
合并多个commit记录 假设我们当前有三个commit信息,现在要将commit hash为 23f92c 和 409978 合并 //git rebase -i HEAD~3 那么我们可以使用 r ...
- C#写鞍点问题
题目: 编写程序,找一找一个二维数组中的鞍点(即该位置上的元素值在行中最大,在列上最小.有可能数组没有鞍点). 要求 * 二维数组的大小.数组元素的值在运行时输入: * 程序有友好的提示信息 usin ...
- 5.C++里的4种新型类型转换
1首先来回顾C的强制转换 大家都知道,在编译C语言中的强制转换时,编译器不会检查转换是否成功,都会编译正确. 比如: #include "stdio.h" struct Posit ...
- Python数据结构之二——tuple(元组)
Python版本:3.6.2 操作系统:Windows 作者:SmallWZQ 列表和元组是Python中最常见的内建序列.元组与列表一样,但是tuple一旦创建就不能修改.创建元组的语法非常简单 ...
- qt的编译
cp qt-everywhere-opensource-src-5.5.0.tar.gz /opt/qt/2.1 解压qt源码 sudo tar xzf qt-everywhere-opensourc ...