API接口通訊參數規范(2)


  針對【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==0)
            {
                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>1</Code>
    <Msg>操作成功</Msg>
  </ErrorCode>
  <ErrorCode>
    <Code>10</Code>
    <Msg>操作失敗</Msg>
  </ErrorCode>
  <ErrorCode>
    <Code>11</Code>
    <Msg>登陸失敗</Msg>
  </ErrorCode>
  <ErrorCode>
    <Code>13</Code>
    <Msg>參數不正確</Msg>
  </ErrorCode>
    <ErrorCode>
    <Code>20</Code>
    <Msg>用戶不存在</Msg>
  </ErrorCode>
  <ErrorCode>
    <Code>21</Code>
    <Msg>沒有數據</Msg>
  </ErrorCode>
</ArrayOfErrorCode>

  再看看我們這個ResultCode枚舉,對比上篇文章,已經不需要DisplayAttribute了

  public enum ResultCode
    {
        /// <summary>
        /// 操作成功
        ///</summary>
        Ok = 1,

        /// <summary>
        /// 操作失敗
        ///</summary>
        Fail = 10,

        /// <summary>
        /// 登陸失敗
        ///</summary>
        LoginFail = 11,
        
        /// <summary>
        /// 參數不正確
        ///</summary>
        InvalidParams = 13,

        /// <summary>
        /// 用戶不存在
        ///</summary>
        NoSuchUser = 20,

        /// <summary>
        /// 沒有該數據
        ///</summary>
        NoRecord = 21,

    }

  那這種情況ResultCode對我們的意義是什么呢?且看下面例子

//情況1 
return Result.FromCode(13);

//情況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。

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM