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

  问题1

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

  XML方案

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

      /// <summary>
/// 结果消息
/// </summary>
public string Message
{
get { return _message ?? XmlResultCodeHelper.GetResultMsg((int)Code); }
set { _message = value; }
}

  看看我们的这个帮助类  

    /// <summary>
/// xml结果码帮助类
/// </summary>
public class XmlResultCodeHelper
{
private static List<XmlResultCode> xmlResultCode = new List<XmlResultCode>(); //获取xml里面对应的msg
public static string GetResultMsg(int key)
{
if (xmlResultCode.Count==)
{
dynamic type = (new ErrorCodes()).GetType();
string currentDirectory = Path.GetDirectoryName(type.Assembly.Location);
string path = currentDirectory + "\\XmlResultCodes.xml";
xmlResultCode= path.XmlDeserializeFromFile<List<XmlResultCode>>();
} var code = xmlResultCode.FirstOrDefault(q => q.Code == key);
if(null == code)
throw new InvalidOperationException("没有配置对应的xml节点");
return code.Msg;
} } /// <summary>
/// xml结果码
/// </summary>
public class XmlResultCode
{
public int Code { get; set; } public string Msg { get; set; }
}

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

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

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfErrorCode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ErrorCode>
<Code></Code>
<Msg>操作成功</Msg>
</ErrorCode>
<ErrorCode>
<Code></Code>
<Msg>操作失败</Msg>
</ErrorCode>
<ErrorCode>
<Code></Code>
<Msg>登陆失败</Msg>
</ErrorCode>
<ErrorCode>
<Code></Code>
<Msg>参数不正确</Msg>
</ErrorCode>
<ErrorCode>
<Code></Code>
<Msg>用户不存在</Msg>
</ErrorCode>
<ErrorCode>
<Code></Code>
<Msg>没有数据</Msg>
</ErrorCode>
</ArrayOfErrorCode>

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

  public enum ResultCode
{
/// <summary>
/// 操作成功
///</summary>
Ok = , /// <summary>
/// 操作失败
///</summary>
Fail = , /// <summary>
/// 登陆失败
///</summary>
LoginFail = , /// <summary>
/// 参数不正确
///</summary>
InvalidParams = , /// <summary>
/// 用户不存在
///</summary>
NoSuchUser = , /// <summary>
/// 没有该数据
///</summary>
NoRecord = , }

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

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

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

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

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

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

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

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

  问题2

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

    public class ResultCodeHelper
{
public static string GetResultMsg(int key)
{
//从redis数据库根据key获取到value
}
}

  这里只是伪代码,大家根据自己的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. C#和C++除了语法上的差别外,还有什么其他的区别

    C#与C++的区别: 1.C#有垃圾自动处理机制,所以程序员不用担心对象的内存的释放问题: 2.C#严禁使用指针,但是非要使用的话,只能在unsafe程序块中的使用: 3.C#只有单继承: 4.C#必 ...

  2. [Noi2015]软件包管理器 BZOJ4196

    分析:水题 每次安装的时候和根节点求lca的过程中区间覆盖+区间查询 每次删除的时候查询子树中安装的数量+区间覆盖 附上代码: #include <cstdio> #include < ...

  3. Ubuntu配置tomcat9

    buntu 安装jdk:[链接] Ubuntu安装eclipse:[链接] Ubuntu下安装MySQL与mysql workbench:[链接] Ubuntu配置tomcat9:[链接] Ubunt ...

  4. ASP.NET Core的实时库: SignalR -- 预备知识

    大纲 本系列会分为2-3篇文章. 第一篇介绍SignalR的预备知识和原理 然后会介绍SignalR和如何在ASP.NET Core里使用SignalR. 本文的目录如下: 实时Web简述 Long ...

  5. 由ORACLE:ORA-28001: the password has expired(密码过期)引起ODI资料库连接失败

    今天,连接ODI,出现下面的错误 oracle.odi.core.config.WorkRepositoryResourceFailureException: ODI-10182: 资料档案库访问期间 ...

  6. ES6--浅析Promise内部结构

    首发地址:sau交流学习社区 一.前言 什么是promise?promsie的核心是什么?promise如何解决回调地狱的?等问题 1.什么是promise?promise是表示异步操作的最终结果:可 ...

  7. SpringBoot集成Lombok,应用+源码解析,让代码优雅起来

    一.Lombok简介 (1)Lombok官网(https://projectlombok.org/)对lombok的介绍 (2)GitHub项目地址:https://github.com/rzwits ...

  8. 【由浅至深】redis 实现发布订阅的几种方式

    非常感谢依乐祝发表文章<.NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐>,对csredis作了一次完整的诠释. 前言 提到消息队列,最熟悉无疑是 rabbitmq,它基 ...

  9. windows下,读取快捷方式lnk所指向的路径

    BOOL GetLnkFileName( OUT PWSTR pLnkName, OUT PWSTR OepnFileNameBuufer, IN DWORD OpenFileNameBufferSi ...

  10. 递归一个List<T>,可自己根据需要改造为通用型。

    /// <summary> /// 递归一个List<ProvinceOrg> /// </summary> /// <returns></ret ...