REST 全称是 Representational State Transfer, 有人说它是一种风格, 并非一种标准, 个人觉得挺有道理. 它本身并没有创造新的技术, 组件与服务, 更像是告诉大家如何更好地使用现有 web 标准中的一些准则和约束, 也不可否认, RESTFul 是目前最流行的 API 设计规范, 用于 Web 数据接口的设计.
RESTful 风格的 API, 在 HTTP 协议上使用的是标准 HTTP 方法, GET,PUT,POST 和 DELETE 等.
常用实践
(1)API 返回结果通常为 JSON 形式, 请求的头部属性 Accept 通常设置为 application/JSON
(2) 请求的 Body 数据部分使用 JSON 形式
(3) 鉴权信息使用 JWT 等形式的授权码方式, 放在请求头部属性中传输, 属性名称自定义, 如 auth,token 等等
辅助类设计
(1) 属性定义
定义属性: TokenHeaderName
上述实践描述中, 自定义部分为鉴权信息在头部属性中的名称, 定义该属性表示这个名称.
定义属性: DefaultToken
考虑到鉴权信息在某些场景下可初始为一个固定值, 定义该属性在默认情况下使用.
具体定义如下:
- // 鉴权 token 的请求头属性名称
- public String TokenHeaderName {
- get; set;
- }
- // 默认的鉴权 token 信息
- public String DefaultToken {
- get; set;
- }
(2) 方法定义
方法定义跟标准的 HTTP 方法一致, 这里定义常用的 Get,Put,Post,Delete 方法.
再抽取其中会重复的部分形成一些私有方法来复用, 再重载一些方法使得可以应用默认参数值.
(2.1) 构造方法
构造时可以指定鉴权头部属性名和 token, 也可以不指定.
- public RestApiVisitHelper()
- {
- }
- // 构造时设置鉴权 token 的请求头属性名称
- public RestApiVisitHelper(String tokenHeaderName)
- {
- TokenHeaderName = tokenHeaderName;
- }
- // 构造时设置鉴权 token 的请求头属性名称, 以及默认的 token 值
- public RestApiVisitHelper(String tokenHeaderName, String defaultToken){
- TokenHeaderName = tokenHeaderName;
- DefaultToken = defaultToken;
- }
(2.2) 访问所需辅助方法
(2.2.1) 创建 WebClient, 设置好相关属性, 包括鉴权头部信息
- // 创建 WebClient 并设置好 token 信息
- private WebClient CreateWebClient(String token)
- {
- System.NET.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
- System.NET.WebClient webClientObj = new System.NET.WebClient();
- webClientObj.Headers.Add("Accept", "application/json");
- if (!String.IsNullOrEmpty(TokenHeaderName) && !String.IsNullOrEmpty(token))
- {
- webClientObj.Headers.Add(TokenHeaderName, token);
- }
- webClientObj.Encoding = Encoding.UTF8;
- return webClientObj;
- }
(2.2.2) 将查询参数格式化拼接成最终 url
- // 将查询参数格式化拼接到 url 上形成最终的访问地址
- private String FormatUrl(String apiUrl, Hashtable queryParams)
- {
- String queryString = "";
- foreach (var k in queryParams.Keys)
- {
- if (!String.IsNullOrEmpty(queryString))
- {
- queryString += "&";
- }
- queryString += String.Format("{0}={1}", k, queryParams[k]);
- }
- if (!String.IsNullOrEmpty(queryString))
- {
- apiUrl += "?" + queryString;
- }
- return apiUrl;
- }
(2.2.3) 异常统一处理
出现请求异常时, 可以统一进行处理, 具体返回结果可自行定义.
- // 异常时返回的信息: 应该根据实际需要进行返回
- private String WhenError(Exception e)
- {
- JObject result = new JObject();
- result["err_code"] = -1;
- if (e is WebException)
- {
- var we = (WebException)e;
- if (we.Response != null) // 如果有输出则仍然返回实际输出
- {
- return new StreamReader(we.Response.GetResponseStream()).ReadToEnd();
- }
- else
- {
- result["err_msg"] = we.Message;
- }
- }
- else
- {
- result["err_msg"] = e.Message;
- }
- return result.ToString(Newtonsoft.JSON.Formatting.None);
- }
(2.3) 公开方法具体实现
有了以上辅助方法, 实现代码会变得简洁, 且各个方法代码结构类似. 以下以 Post 方法 (包括重载) 为例展示基本实现.
- /// <summary>
- /// Post API 返回结果文本, 使用默认的鉴权 token
- /// </summary>
- /// <param name="apiUrl"></param>
- /// <param name="queryParams"></param>
- /// <param name="body"></param>
- /// <returns></returns>
- public String Post(string apiUrl, Hashtable queryParams, JObject body)
- {
- return Post(apiUrl, queryParams, body, DefaultToken);
- }
- /// <summary>
- /// Post API 返回结果文本
- /// </summary>
- /// <param name="apiUrl"></param>
- /// <param name="queryParams"></param>
- /// <param name="body"></param>
- /// <param name="token"></param>
- /// <returns></returns>
- public String Post(string apiUrl, Hashtable queryParams, JObject body, String token)
- {
- System.NET.WebClient webClientObj = CreateWebClient(token);
- apiUrl = FormatUrl(apiUrl, queryParams);
- try
- {
- String result = webClientObj.UploadString(apiUrl, "POST", body.ToString(Newtonsoft.JSON.Formatting.None));
- return result;
- }
- catch (Exception ce)
- {
- return WhenError(ce);
- }
- }
完整源码
来源: https://www.cnblogs.com/timeddd/p/11126278.html