java api接口怎么寫_Java 如何設計 API 接口,實現統一格式返回?

來源:老顧聊技術

  • 前言

  • 接口交互

  • 返回格式

  • 控制層Controller

  • 美觀美化

  • 優雅優化

  • 實現方案


前言

在移動互聯網,分布式、微服務盛行的今天,現在項目絕大部分都采用的微服務框架,前后端分離方式,(題外話:前后端的工作職責越來越明確,現在的前端都稱之為大前端,技術棧以及生態圈都已經非常成熟;以前后端人員瞧不起前端人員,那現在后端人員要重新認識一下前端,前端已經很成體系了)。

一般系統的大致整體架構圖如下:

971e172b6e7eb7c2c77b039d76fb0052.png

需要說明的是,有些小伙伴會回復說,這個架構太簡單了吧,太low了,什么網關啊,緩存啊,消息中間件啊,都沒有。因為老顧這篇主要介紹的是API接口,所以我們聚焦點,其他的模塊小伙伴們自行去補充。

接口交互

前端和后端進行交互,前端按照約定請求URL路徑,并傳入相關參數,后端服務器接收請求,進行業務處理,返回數據給前端。

針對URL路徑的restful風格,以及傳入參數的公共請求頭的要求(如:app_version,api_version,device等),老顧這里就不介紹了,小伙伴們可以自行去了解,也比較簡單。

后端服務器如何實現把數據返回給前端?

返回格式

后端返回給前端我們一般用JSON體方式,定義如下:

{
??#返回狀態碼
??code:integer,
??#返回信息描述
??message:string,
??#返回值
??data:object
}

CODE狀態碼

code返回狀態碼,一般小伙伴們是在開發的時候需要什么,就添加什么。

如接口要返回用戶權限異常,我們加一個狀態碼為101吧,下一次又要加一個數據參數異常,就加一個102的狀態碼。這樣雖然能夠照常滿足業務,但狀態碼太凌亂了

我們應該可以參考HTTP請求返回的狀態碼

:下面是常見的HTTP狀態碼:
200?-?請求成功
301?-?資源(網頁等)被永久轉移到其它URL
404?-?請求的資源(網頁等)不存在
500?-?內部服務器錯誤
e11fbc11e7052f08a766e678d08c7a5f.png

我們可以參考這樣的設計,這樣的好處就把錯誤類型歸類到某個區間內,如果區間不夠,可以設計成4位數。

#1000~1999?區間表示參數錯誤
#2000~2999?區間表示用戶錯誤
#3000~3999?區間表示接口異常

這樣前端開發人員在得到返回值后,根據狀態碼就可以知道,大概什么錯誤,再根據message相關的信息描述,可以快速定位。

Message

這個字段相對理解比較簡單,就是發生錯誤時,如何友好的進行提示。一般的設計是和code狀態碼一起設計,如

b929200e5d670abf63d0b63fbf013417.png

再在枚舉中定義,狀態碼

32a7fa34e203544eb929c21a7ac45fb0.png

狀態碼和信息就會一一對應,比較好維護。

Data

返回數據體,JSON格式,根據不同的業務又不同的JSON體。

我們要設計一個返回體類Result

5d64e6947aa70505581e92fc686f57b0.png

控制層Controller

我們會在controller層處理業務請求,并返回給前端,以order訂單為例

767c16fd747b38e9faba24c958de469e.png

我們看到在獲得order對象之后,我們是用的Result構造方法進行包裝賦值,然后進行返回。小伙伴們有沒有發現,構造方法這樣的包裝是不是很麻煩,我們可以優化一下。

美觀美化

我們可以在Result類中,加入靜態方法,一看就懂

be17badc95e34faf5edee9d93712a19e.png

那我們來改造一下Controller

abcd866875fab2b0f798ab89bdbcc20c.png

代碼是不是比較簡潔了,也美觀了。

優雅優化

上面我們看到在Result類中增加了靜態方法,使得業務處理代碼簡潔了。但小伙伴們有沒有發現這樣有幾個問題:

1、每個方法的返回都是Result封裝對象,沒有業務含義

2、在業務代碼中,成功的時候我們調用Result.success,異常錯誤調用Result.failure。是不是很多余

3、上面的代碼,判斷id是否為null,其實我們可以使用hibernate validate做校驗,沒有必要在方法體中做判斷。

我們最好的方式直接返回真實業務對象,最好不要改變之前的業務方式,如下圖

55784a6c5893d9c5b094895cb37839a2.png

這個和我們平時的代碼是一樣的,非常直觀,直接返回order對象,這樣是不是很完美。那實現方案是什么呢?

實現方案

小伙伴們怎么去實現是不是有點思路,在這個過程中,我們需要做幾個事情

1、定義一個注解@ResponseResult,表示這個接口返回的值需要包裝一下

2、攔截請求,判斷此請求是否需要被@ResponseResult注解

3、核心步驟就是實現接口ResponseBodyAdvice和@ControllerAdvice,判斷是否需要包裝返回值,如果需要,就把Controller接口的返回值進行重寫。

注解類

用來標記方法的返回值,是否需要包裝

af12bd5ab23c54b5005c3c1ff7562682.png

攔截器

攔截請求,是否此請求返回的值需要包裝,其實就是運行的時候,解析@ResponseResult注解

82557869c41782b76573d7261acd96a0.png

此代碼核心思想,就是獲取此請求,是否需要返回值包裝,設置一個屬性標記。

重寫返回體

1f29394017036edffa7fd5e582badf07.png

上面代碼就是判斷是否需要返回值包裝,如果需要就直接包裝。這里我們只處理了正常成功的包裝,如果方法體報異常怎么辦?處理異常也比較簡單,只要判斷body是否為異常類。

b20f41942097d276f23a4c8d44423a86.png

怎么做全局的異常處理,篇幅原因,老顧這里就不做介紹了,只要思路理清楚了,自行改造就行。

重寫Controller

f8a76b7102c05d884c3bbaca21651396.png

在控制器類上或者方法體上加上@ResponseResult注解,這樣就ok了,簡單吧。到此返回的設計思路完成,是不是又簡潔,又優雅。

這個方案還有沒有別的優化空間,當然是有的。如:每次請求都要反射一下,獲取請求的方法是否需要包裝,其實可以做個緩存,不需要每次都需要解析。當然整體思路了解,小伙伴們就可以在此基礎上面自行擴展,

程序汪往期精彩文章

程序汪最近整理的BAT大小廠面試題(面試題目錄推薦)

目錄:我把精華文章都整理出來了

Java碩士京東工作1年,跳槽后他期望薪資26K,大家感覺他可以嗎

經驗分享:一本學歷大三Java粉絲順利拿下實習offer,他放棄了考研

經驗分享:Java1年經驗16K外派支付寶,你們說香嗎

面經分享:畢業西電Java工作3年拿到了30Koffer

經驗分享:36000元培訓1年半Java,一個培訓踩坑經歷

090564a78db41ca6daa0e538f94a1398.png

給個[在看],是對程序汪最大的支持

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446239.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446239.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446239.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java 輸出學生成績和成績等級

題目 從鍵盤讀入學生成績,找出最高分,并輸出學生成績等級。?成績>最高分-10 等級為’A’?成績>最高分-20 等級為’B’?成績>最高分-30 等級為’C’?其余 等級為’D’提示:先讀入學生人數,根據人數創建int數組&#…

STL源碼剖析 multiset 和 multimap

multiset和set完全相同,唯一的差別在于允許鍵值的重復,因此底層操作使用的是紅黑樹的insert_equal() 而不是insert_unique()multimap和map完全相同,唯一的差別在于允許鍵值的重復,因此底層操作使用的是紅黑樹的insert_equal() 而不…

java 二維數組

聲明和初始化 靜態初始化 // 靜態初始化: // 一維數組int[] arr1_1 {1, 2, 4};System.out.println(Arrays.toString(arr1_1)); // 二維數組int[][] arr1_2 {{1, 2}, {4, 5}, {9, 10}};for (int[] i :arr1_2) {System.out.print(Arrays.toS…

STL源碼剖析 hashtable

二叉搜索樹具有對數平均時間的表現,但是這個需要滿足的假設前提是輸入的數據需要具備隨機性hashtable 散列表這種結構在插入、刪除、搜尋等操作層面上也具有常數平均時間的表現。而且不需要依賴元素的隨機性,這種表現是以統計為基礎的 hashtable的概述 …

append在python里是什么意思_“一棵綠蘿七個鬼”是什么意思?臥室里到底能不能養綠蘿!...

很多人都喜歡在家里養盆綠蘿,一是能凈化室內空氣,讓家里綠意濃濃,更有生機一些;二是綠蘿好養,水培土培都行,養著也省心。在養花界有一句俗語:“一棵綠蘿七個鬼”,這句話是什么意思呢…

java 二分查找

注意 二分查找要求原數組為有序序列,從小到大 遞歸解法 public class problem9 {public static void main(String[] args) {int[] arr {1,2,3,4,6,7};int left 0;int right arr.length - 1;int value 2;System.out.println(Arrays.toString(arr));int index …

C++for_each| bind1st | ptr_fun | std::function的用法

c for_each 用法_小鍵233-CSDN博客 傳入參數 要傳入參數給global function ,需要使用 ptr_fun() 這個 function adapter 將global function 轉成function object , 然后再用bind2nd() 將參數bind成一個function object。(這句話好拗口) void fun(int i…

java三個柱子漢諾塔問題

題目 移動盤子,每一次只能移動一個,小盤子在大盤子上。 打印1 from A to B過程 注意 1)盤子編號的變化和輔助柱子的變化 2)當盤子編號為1時,結束遞歸,此時移動結束 代碼 package p2;/*** Illustratio…

python遍歷txt每一行_python – 計算(和寫入)文本文件中每一行的...

第一次在堆棧中發布 – 總是發現以前的問題足以解決我的問題!我遇到的主要問題是邏輯……即使是偽代碼答案也會很棒. 我正在使用python從文本文件的每一行讀取數據,格式如下: This is a tweet captured from the twitter api #hashtag http://url.com/si…

java楊輝三角形

題目 代碼1 public class YangHuiTriangle {public static void main(String[] args) {print(10);}public static void print(int num) {int[][] arr new int[num][];for (int i 0; i < num; i) { // 第一行有 1 個元素, 第 n 行有 n 個元素arr[i] new int[i…

python子類繼承父類屬性實例_python – 從子類內的父類訪問屬性

在類定義期間,沒有任何繼承的屬性可用&#xff1a; >>> class Super(object): class_attribute None def instance_method(self): pass >>> class Sub(Super): foo class_attribute Traceback (most recent call last): File "", line 1, in cl…

STL源碼剖析 算法開篇

STL源碼剖析 算法章節 算法總覽_CHYabc123456hh的博客-CSDN博客 質變算法 質變算法 - 會改變操作對象的數值&#xff0c;比如互換、替換、填寫、刪除、排列組合、分隔、隨機重排、排序等 #include <iostream> #include <vector>int main(){int ia[] {22,30,20,34…

java 隨機數一維數組

題目1 創建一個長度為6的int型數組&#xff0c;要求數組元素的值都在1-30之間&#xff0c;且是隨機賦值。同時&#xff0c;要求元素的值各不相同 代碼1 public class ArrayTest2 {public static void main(String[] args) {generateArray(6);}public static void generateAr…

STL源碼剖析 數值算法 accumulate | adjacent_difference | inner_product | partial_sum | power | itoa

//版本1 template <class InputIterator,class T> T accumulate(InputIterator first,InputIterator last,T init){for(;first ! last; first){init *first; //將每個元素數值累加到init身上}return init; }//版本2 template <class InputIterator,class T,class Bin…

python官網網址是什么意思_大家都是怎么部署python網站的?

flaskgunicornnginx 作者&#xff1a;Python小白 鏈接&#xff1a;centos下通過gunicorn和nginx部署Flask項目 - Python小白的文章 - 知乎專欄 來源&#xff1a;知乎 著作權歸作者所有。商業轉載請聯系作者獲得授權&#xff0c;非商業轉載請注明出處。 之前用Flask寫了個解析Tu…

java回形數矩陣

題目 從鍵盤輸入一個整數&#xff08;1~20&#xff09; 則以該數字為矩陣的大小&#xff0c;把1,2,3…n*n 的數字按照順時針螺旋的形式填入其中。例如&#xff1a; 輸入數字2&#xff0c;則程序輸出&#xff1a; 1 2 4 3 輸入數字3&#xff0c;則程序輸出&#xff1a; 1 2 3 8…

STL源碼剖析 基本算法 equal | fill | iter_awap | lexicographical_compare | max | min | swap |mismatch

Equal 兩個序列在[first,last)區間內相等&#xff0c;equal()返回true。以第一個序列作為基準&#xff0c;如果第二序列元素多不予考慮&#xff0c;如果要保證兩個序列完全相等需要比較元素的個數 if(vec1.size() vec2.size() && equal(vec1.begin(),vec1.end(),vec2…

svm分類器訓練詳細步驟_「五分鐘機器學習」向量支持機SVM——學霸中的戰斗機...

大家好&#xff0c;我是愛講故事的某某某。 歡迎來到今天的【五分鐘機器學習】專欄內容 --《向量支持機SVM》 今天的內容將詳細介紹SVM這個算法的訓練過程以及他的主要優缺點&#xff0c;還沒有看過的小伙伴歡迎去補番&#xff1a;【五分鐘機器學習】向量支持機SVM——學霸中的…

java一維數組的復制

題目 使用簡單數組(1)創建一個名為ArrayTest的類&#xff0c;在main()方法中聲明array1和array2兩個變量&#xff0c;他們是int[]類型的數組。(2)使用大括號{}&#xff0c;把array1初始化為8個素數&#xff1a;2,3,5,7,11,13,17,19。(3)顯示array1的內容。(4)賦值array2變量等…

STL源碼剖析 數值算法 copy 算法

copy復制操作&#xff0c;其操作通過使用assignment operator 。針對使用trivial assignment operator的元素型別可以直接使用內存直接復制行為(使用C函數 memove或者memcpy)節約時間。還可以通過函數重載(function overloading)、型別特性(type traits)、偏特化(partial speci…