针对【API接口通讯参数规范】这篇文章留下的几个问题进行探讨。

  问题1

  试想一下,如果一个http请求返回一个500给我们,那我们是不是都不用看详情都知道该次请求发生了什么?这正是一个标准的结果码意义所在。在公司所有的系统中,API遵循同一套结果码,那这样同事A在调用同事B的接口时,对于返回的结果码是非常具有可读性的,我们不用面对面交流都知道返回的结果是一个什么样的情况。  

  XML方案

  在此先给出上一篇文章针对Result的另一个方案,是基于XML来定义结果码的,可能有些公司喜欢XML这种配置文件,因为可以不用重新发布应用程序(其实大多数情况下还是需要重新发布的,后面会讲解)。这里面的主要变化是我们不再从枚举ResultCode中获取提示信息,这些提示信息会放在XML上,看看我们的Result中的Message属性的变化

  1.   /// <summary>
  2. /// 结果消息
  3. /// </summary>
  4. public string Message
  5. {
  6. get { return _message ?? XmlResultCodeHelper.GetResultMsg((int)Code); }
  7. set { _message = value; }
  8. }

  看看我们的这个帮助类  

  1. /// <summary>
  2. /// xml结果码帮助类
  3. /// </summary>
  4. public class XmlResultCodeHelper
  5. {
  6. private static List<XmlResultCode> xmlResultCode = new List<XmlResultCode>();
  7.  
  8. //获取xml里面对应的msg
  9. public static string GetResultMsg(int key)
  10. {
  11. if (xmlResultCode.Count==)
  12. {
  13. dynamic type = (new ErrorCodes()).GetType();
  14. string currentDirectory = Path.GetDirectoryName(type.Assembly.Location);
  15. string path = currentDirectory + "\\XmlResultCodes.xml";
  16. xmlResultCode= path.XmlDeserializeFromFile<List<XmlResultCode>>();
  17. }
  18.  
  19. var code = xmlResultCode.FirstOrDefault(q => q.Code == key);
  20. if(null == code)
  21. throw new InvalidOperationException("没有配置对应的xml节点");
  22. return code.Msg;
  23. }
  24.  
  25. }
  26.  
  27. /// <summary>
  28. /// xml结果码
  29. /// </summary>
  30. public class XmlResultCode
  31. {
  32. public int Code { get; set; }
  33.  
  34. public string Msg { get; set; }
  35. }

  这个类主要是帮助我们获取到XmlResultCodes.xml并且返回里面对应的msg,这方法里面的xml反序列方法我就不再贴出来了,大家百度一下即可。

  看一下我们的XmlResultCodes.xml,这里看得出是一个键值对  

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <ArrayOfErrorCode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  3. <ErrorCode>
  4. <Code></Code>
  5. <Msg>操作成功</Msg>
  6. </ErrorCode>
  7. <ErrorCode>
  8. <Code></Code>
  9. <Msg>操作失败</Msg>
  10. </ErrorCode>
  11. <ErrorCode>
  12. <Code></Code>
  13. <Msg>登陆失败</Msg>
  14. </ErrorCode>
  15. <ErrorCode>
  16. <Code></Code>
  17. <Msg>参数不正确</Msg>
  18. </ErrorCode>
  19. <ErrorCode>
  20. <Code></Code>
  21. <Msg>用户不存在</Msg>
  22. </ErrorCode>
  23. <ErrorCode>
  24. <Code></Code>
  25. <Msg>没有数据</Msg>
  26. </ErrorCode>
  27. </ArrayOfErrorCode>

  再看看我们这个ResultCode枚举,对比上篇文章,已经不需要DisplayAttribute了

  1.   public enum ResultCode
  2. {
  3. /// <summary>
  4. /// 操作成功
  5. ///</summary>
  6. Ok = ,
  7.  
  8. /// <summary>
  9. /// 操作失败
  10. ///</summary>
  11. Fail = ,
  12.  
  13. /// <summary>
  14. /// 登陆失败
  15. ///</summary>
  16. LoginFail = ,
  17.  
  18. /// <summary>
  19. /// 参数不正确
  20. ///</summary>
  21. InvalidParams = ,
  22.  
  23. /// <summary>
  24. /// 用户不存在
  25. ///</summary>
  26. NoSuchUser = ,
  27.  
  28. /// <summary>
  29. /// 没有该数据
  30. ///</summary>
  31. NoRecord = ,
  32.  
  33. }

  那这种情况ResultCode对我们的意义是什么呢?且看下面例子

  1. //情况1
  2. return Result.FromCode();
  3.  
  4. //情况2
  5. return Result.FromCode(ResultCode.InvalidParams);

  我们虽然英文口语不一定流利:),但是凭借我们的睿智,肯定会让我们选择情况2使程序具有更高的可读性,不然新人接手项目,吐槽是少不了的,难保自己过了段时间再看这样的设计,这返回的13是什么鬼?

  OK,XML的方案基本可以了,总结一下步骤:

  1.  在ResultCode中定义好自己的英文(使程序具有更高的可读性)和对应枚举的数值

  2.  在XmlResultCodes.xml中定义这个数值对应的提示信息

  同样我们也会审视这个设计方案的问题所在:为什么会采用XML?就是冲着不用重新发布嘛。是的,改提示信息是可以不用重新发布,但是在xml里面添加了新的节点呢?添加了之后我们得用啊,一样要在业务中调用这个新的节点,还不是一样要重新发布?这样看来我们基于这个XML的设计方案并没有完全达到我们的初衷的。

  怎么办?且看下面的问题。

  问题2

  我们如何做到统一呢?中心式的管理,在管理后台中,把所有的结果码和对应的消息都写入数据库,然后通过Redis加载作为缓存,在获取提示信息的时候访问Redis返回我们需要的信息。

  1. public class ResultCodeHelper
  2. {
  3. public static string GetResultMsg(int key)
  4. {
  5. //从redis数据库根据key获取到value
  6. }
  7. }

  这里只是伪代码,大家根据自己的Redis的熟知情况设计方案。

  现在这个ResultCode的增删改都只能让管理员在管理后台操作了,开发人员最好是有权限能查看到ResultCode的所有结果码和信息,这样在新增之前才能知道是否存在类似的结果码进而避免重复。修改和删除结果码?最好不要,你有见过Http状态码的更改吗?这种公司级别的通讯规范,作为基础设施架构就最好先设计和定义,后续项目多起来,都可以有据可依。

  来看一下我们结果码定义和使用的流程:

  1. ResultCode在管理后台的定义和储存

  2. 加载到Redis并获取对应值的信息

  3. 每个项目都定义好自己的ResultCode对应的枚举和值(使程序具有更高的可读性)

  至此我们通过DisplayAttribute和XML获取提示信息这两种方案都已经被分布式缓存Redis方案代替了,我们做了那么多,并且耦合了Redis缓存,这样做究竟有什么好处呢?就像我们的标题阐述的主题一样,规范!规范会让后续的项目管理花费更少的effor。

  让我知道如果你有更好的想法!

API接口通讯参数规范(2)的更多相关文章

  1. API接口通讯参数规范

    通常在很多的公司里面,对于接口的返回值没做太大规范,所以会比较常看到各个项目各自定义随意的返回值,比如以下情况: 1. 直接返回bool值(True或者False) 2. 返回void,只要不是异常信 ...

  2. Restful API 接口设计标准及规范

    Restful API 接口设计标准以及规范 RESTful概念 理解和评估以网络为基础的应用软件的架构设计,得到一个功能强.性能好.适宜通信的架构.REST指的是一组架构约束条件和原则." ...

  3. API接口防止参数篡改和重放攻击

    {近期领导要求我对公司业务的支付类的ocr接口做研究,是否存在支付接口重放攻击,so.....} API重放攻击(Replay Attacks)又称重播攻击.回放攻击.他的原理就是把之前窃听到的数据原 ...

  4. RESTful API接口文档规范小坑

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. 前后端分离的开发模式,假如使用的是基于RESTful API的七层通讯协议,在联调的时候,如何避免配合过程中出现问 ...

  5. 如何写出安全的API接口(参数加密+超时处理+私钥验证+Https)- 续(附demo)

    上篇文章说到接口安全的设计思路,如果没有看到上篇博客,建议看完再来看这个. 通过园友们的讨论,以及我自己查了些资料,然后对接口安全做一个相对完善的总结,承诺给大家写个demo,今天一并放出. 对于安全 ...

  6. Spring框架学习笔记(9)——API接口设计相关知识及具体编码实现

    最近需要设计一个API服务器,想要把API接口搞得规范一下,就通过网上搜集到了一些资料,以下便是自己的一些理解以及相关的具体实现 本文采用的是spring boot+maven的方案 restful规 ...

  7. API 接口开发规范

    整体规范建议采用RESTful 方式来实施. 协议 API与用户的通信协议,总是使用HTTPs协议,确保交互数据的传输安全. 域名 应该尽量将API部署在专用域名之下.https://api.exam ...

  8. day71:drf:API接口&Restful API规范&Django Rest Framework&drf中的序列化和反序列化功能

    目录 1.web应用模式 2.API接口 3.Restful API规范 4.序列化 5.Django Rest Framework 1.drf的简单介绍 2.drf的特点 3.如何安装drf 4.d ...

  9. 后端API接口的错误信息返回规范

    前言 最近我司要制定开发规范.在讨论接口返回的时候,后端的同事询问我们前端,错误信息的返回,前端有什么意见? 所以做了一些调研给到后端的同事做参考. 错误信息返回 在使用API时无可避免地会因为各种情 ...

随机推荐

  1. ANSI 和 UNICODE 的函数对应表

    ANSI        UNICODE           通用(char.h)    (wchar.h)        (tchar.h) char         wchar_t         ...

  2. BZOJ_1934_[Shoi2007]Vote 善意的投票

    BZOJ_1934_[Shoi2007]Vote 善意的投票 Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然 ...

  3. laravel 中路由的快速设置(只需一个控制器名就ok) 不用具体到方法

    routes/web.php 设置路由 Route::group(['middleware' => ['\iqiyi\Http\Middleware\VerifyCsrfToken::class ...

  4. Windows上安装配置SSH教程(3)——在Windows系统上安装与配置WinSCP

    知识点汇总:http://www.cnblogs.com/feipeng8848/p/8559803.html -------------------- 首先确认客户端已经安装了OpenSSH.安装方 ...

  5. AMBA总线协议AHB、APB

    一.什么是AMBA总线 AMBA总线规范是ARM公司提出的总线规范,被大多数SoC设计采用,它规定了AHB (Advanced High-performance Bus).ASB (Advanced ...

  6. appium-desktop录制脚本二次开发,生成我司自动化脚本

    目的 通过对appium-desktop脚本录制功能进行二次开发,使录制的java脚本符合我司自动化框架要求. 实现步骤 1.增加元素名称的输入框 由于ATK(我司自动化测试框架)脚本中元素是以“ap ...

  7. 带着新人看java虚拟机04(多线程篇)

    我记得最开始接触多进程,多线程这一块的时候我不是怎么理解,为什么要有多线程啊?多线程到底是个什么鬼啊?我一个程序好好的就可以运行为什么要用到多线程啊?反正我是十分费解,即使过了很长时间我还是不是很懂, ...

  8. Android中一个经典理解误区的剖析

    今天,在Q群中有网友(@广州-包晴天)发出了网上的一个相对经典的问题,问题具体见下图. 本来是无意写此文的,但群里多个网友热情不好推却,于是,撰此文予以分析. 从这个问题的陈述中,我们发现,提问者明显 ...

  9. MobileForm控件的使用方式-用.NET(C#)开发APP的学习日志

    今天继续Smobiler开发APP的学习日志,这次是做一个title.toolbar.侧边栏三种效果 样式一 一.          Toolbar 1.       目标样式 我们要实现上图中的效果 ...

  10. 系统的讲解 - PHP 缓存技术

    目录 概述 浏览器缓存 文件缓存 NoSQL缓存 WEB服务器缓存 Opcode缓存 小结 关于缓存的常见问题 概述 缓存已经成了项目中是必不可少的一部分,它是提高性能最好的方式,例如减少网络I/O. ...