剛接到這樣的任務時,沒有感覺到任何壓力,不就是給移動端應用提供數據嗎?那邊發來參數,這邊處理數據,返回JSON。做網站開發時經常使用ajax請求後臺數據,不就是這麼回事嗎。於是,在確認完需求後就開始幹了,很快,進入聯調階段,這個時候各種問題來了,忙得不可開交。吃一塹,長一智,項目結束後總結了下,大致 ...
剛接到這樣的任務時,沒有感覺到任何壓力,不就是給移動端應用提供數據嗎?那邊發來參數,這邊處理數據,返回JSON。做網站開發時經常使用ajax請求後臺數據,不就是這麼回事嗎。於是,在確認完需求後就開始幹了,很快,進入聯調階段,這個時候各種問題來了,忙得不可開交。吃一塹,長一智,項目結束後總結了下,大致分為以下幾點:
一、什麼時候應該增加介面。
一般一個頁面不存在二次請求的需求時,使用一個介面,像一般的詳情頁,個人信息頁等;頁面單一功能又需要二次請求的,像帶分頁功能的列表頁,使用一個介面;頁面含多個功能,其中有一個需要二次請求的,則需要定義多個介面了,比如個人信息頁下帶一個待辦事項的列表,又支持分頁,那如果一個介面返回全部信息的話,以後每次翻頁都要刷新個人信息內容,這樣就造成了不必要的信息傳遞。
二、 應該努力讓介面的URL看上去易懂又美觀。
在創建介面時就應該考慮到介面地址,文件目錄不要太深,個人覺得不應超過三層,層次最好是和APP的菜單層次保持一致,這樣的好處起碼在以後維護也會方便很多。介面地址不應該輕易的改動,包括增加參數,因為這會導致APP重新打包,如果是已經上線,那意味著APP需要升級。
三、參數與返回值。
先說參數,筆者目前的做法是一般查詢採用URL傳參,增改採用POST傳遞JSON字元串提交數據,刪除同樣使用POST方式。再說返回值,我們在項目中所有介面統一返回JOSN數據,並且約定一個格式,比如這個JSON對象含三個Key,分別是data,msg和status,分別代表了返回的數據,data可能是對象或者數組,請求反饋信息和反饋狀態碼,這樣就不用每個介面都說明一遍了。再談一些細節,在高級語言中,數據有多種類型,String,Int,DateTime等等。而序列化為JSON後,全部變為字元串,這個時候沒有給值的欄位就需要註意一下,像值類型,為可空時,序列化後值直接是null表示,沒有引號;為不可空時,值為預設值,同樣沒有引號,而DateTime則帶引號,"0001-01-01T00:00:00";而像引用類型String,無值時,序列化後也變成null,而不是空串"",要想用空串""表示,必須給一個預設值,如String.Empty,說這點是因為當時iOS告訴我說欄位值返回null時,他們那邊報錯。還有一種情況是之前遇到過的,就是數值類型的精度問題,當時介面返回一個價格欄位,伺服器端當然用decimal類型,並且保留兩位小數,但是iOS端接收到的值小數點後卻多出很多位,而Android沒有任何問題,最後只好在序列化前先轉成字元串類型。其它需要包含小數位的數值類型當小數點後全是0時,序列化變為整型,這種情況同樣需要先轉為字元串再序列化。關於DateTime類型,在作為增改參數接收時,就是反序列化後要插入到資料庫,如果你正好使用了Sql Server,又使用了DateTime類型,請註意它的範圍是1753-01-01 00:00:00 到9999-12-31 23:59:59,而空串轉為時間為"0001-01-01 00:00:00",會報異常。最後,筆者感覺,是不是沒有特殊情況,所有欄位都可以給移動端返回字元串呢,像時間類型,手機上要顯示到日,我就不返回時分秒了,以字元串類型返回,這樣以後產品說要顯示時分秒,直接在後臺處理下就OK了,是不是這樣的?
四、介面如何聯調。
這裡的聯調包含兩層含義,一是VS環境下的遠程調試,這個具體方法在網上有很多,在這就不多說了。另一個含義就是和移動端聯合測試軟體功能。這次項目並沒有真正遠程調試幾次,因為記錄了詳細的調試日誌,所以大部分問題都能很快的定位。調試日誌一般都包含了兩項內容:當前環境下的關鍵變數值及當前方法的信息。
五、錯誤處理和返回錯誤碼。
首先,切忌把異常直接拋給調用者。因為這樣不論是對體驗還是定位錯誤都沒有任何益處,而是應該在後臺捕獲,並記錄詳細的日誌,然後定義一套全局的錯誤碼,返回對應的錯誤碼給介面調用者。關於異常的捕獲應該在哪裡處理,個人覺得但應該不是最佳,最外層應該用try catch包裹,並記錄日誌,保證異常不會拋出到調用方,其它位置如果有非托管資源的使用,應該捕獲,然後記錄日誌,釋放資源,並繼續把錯誤向上拋。
六、介面文檔。
提到寫文檔,程式員貌似天生反感,但是開發介面,不寫文檔,似乎是不可能的,並且還要寫得規範,別人能看懂。介面文檔寫得好,真的是件一勞永逸的事,寫一份好文檔省出的時間要遠遠大於寫文檔的時間,當然要做到及時更新,與程式同步。一般介面文檔包含了功能、請求方式(GET/POST)、 地址、參數、返回值、請求示例、返回示例以及全局的安全驗證方式、錯誤碼等。
寫這篇文章的目的就是想把這幾個月的介面開發工作做個總結,結果拖拖拉拉寫了好幾天,寫完再讀時發現都有點變味了。文章中可能很多地方寫到的處理方法或者對知識的理解並不是很正確,希望您不吝賜教,留下寶貴建議。