如何搭建一個能快速迭代業務,且穩定的Java 接口服務

         在Java的web開發世界中,spring boot 如今應該是應用最普遍的的了。spring boot要作一個接口服務的底子真的很快,使用maven 引入幾個spring boot的starter接能夠很快的能夠開始寫接口了。可是他是個基礎框架,它不能保證你寫的代碼不出錯或者少出錯。那如何讓寫的代碼更簡潔,更少出錯呢。這個文章我不想貼代碼。由於我知道你們喜歡拿來主義。因此我最後會把腳手架的代碼放出來。本篇文章只寫我最近一年來不斷對一個系統不斷重構的實踐。前端

一、代碼即文檔mysql

      寫一個接口對spring boot 來講真的很快。你只須要關心業務就行了。接收請求,返回數據spring都爲你作好了。可是寫出來的接口要給前端用吧,因此你須要一個強大的接口文檔工具。開源的swagger2真的是一個很強大的接口文檔生成工具。寫代碼的同時就把文檔寫出來了。真正的作到了代碼即文檔。git

二、寫可維護的接口程序員

      什麼樣的接口是易於擴展的,什麼樣的接口是易維護的。我實踐過程當中發現,不管是什麼方法,咱們保證他是無參/單參是最好維護的。無參就不說了,沒啥好解釋的。爲何要單參數,不少人搞不清楚?相信你們都用AOP作過業務,也清楚AOP在接口的調用過程當中拿到的參數是個數組,在代碼運行期間,你起的那些參數名其實都是被擦除的,對jvm來講沒有任何實際的意義。爲何要單參數是爲了保證這種信息不丟失,或者丟失了無影響。可能這麼解釋仍是一臉懵逼,我爲何要保證接口參數名的信息不丟失/丟失了無影響,那我來講一個具體使用場景你就明白這種設計的好處了。在電商服務中,爲了保證一些訪問頻率高接口的響應,咱們會對這些接口作數據作緩存。怎麼作緩存,不是Java小白都知道用AOP加自定義註解來無侵入代碼邏輯的方式來作緩存。假設如今咱們在redis中用 PRORDUCT_DETAIL:{productId}來作key對商品的信息進行緩存。如今商品進行下架了或者上架了,你的上下架接口想必是一個,經過傳一個productId和saleState來作這件事,若是你把這兩個參數分開寫了,你通用的AOP邏輯裏就沒法精準的對哪個商品的緩存進行刪除。由於你AOP的邏輯裏不知道哪個參數是productId。你就沒法作到精準刪除。若是你是單參數,你須要把productId,saleState封裝成一個Dto類,這樣在調用過程當中你的'productId' 這個屬性名就不會丟失,你就能夠精準的去作自動的緩存失效。這只是一個小的應用場景,更復雜的場景中,多參數合併爲對象來傳參數,這樣的接口若是有業務變更也能更好的擴展。你沒必要爲要了業務須要多傳一個參數的時候須要把全部調用的地方都改動一遍。並且有的上層接口並不必定能拿到你想要的結果,多參的接口會讓你在業務改動的時候,牽一髮而動全身。github

三、下降本身的工做量,才能高效。web

     在咱們寫代碼的時候有不少無腦工做須要作,好比你想寫一個新增商品的接口。幾十個屬性。要存到數據庫的時候,你須要把傳參數的dto轉成po,若是你一個個的手寫set(get)這不讓人崩潰嗎?效率奇差不說,並且容易漏啊。不如作個BaseEntity讓全部的dto和po來繼承的好,BaseEntity提供一個<T> convertTo(Class<T> clazz)來作。經過反射和Spring的BeanUtils來實現一個po的生成,啥你跟說反射的性能低?大家公司缺一個調用100w次多消耗1s的服務器資源嗎?追求系統的性能不要矯正過枉。你的服務真的不缺那100w次多出1s的服務器消耗。我相信國內90%的公司的服務器大部分時間都是‘半睡半醒’的狀態。真把業務能作到QPS缺這1s再說吧。redis

四、一個適合的ORM框架spring

     ORM框架對Java開發來講,最有名的莫過於之前是Mybatis/Hibernate . 如今Mybatis/Spring Data JPA。 從我在公司和我本身在家研究不斷重構本身的代碼來看。我更偏向於Spring Data JPA。說說個人感覺吧!Mybatis框架是個好框架我不否定,可是它須要寫sql的特性就表明了開發效率真的不高。而後他有一個插件Mybatis Plus 標準的增刪改查都不須要寫sql了。卻是解決了這種開發效率低問題。可是我依然強烈推薦JPA做爲ORM。緣由以下:sql

          (1)、在基礎的增刪改查上,用Mybatis Plus 和JPA應該差很少,可是JPA的查詢返回是Optional能避免不少NullPointException的問題。若是你用的是JDK 11 (增長了不少Optional的方法),使用JPA返回的Optional讓你的的代碼優美,簡潔,不容易出錯。數據庫

         (2)、寫法更簡單,Mybatis Plus對屬性查詢須要構建QueryWapper對象,我的感受很囉嗦。Spring Data的 findByXxx更簡潔,多個屬性的查詢用Example來作更簡潔。再複雜點用Query來作也很方便。

         (3)、業務擴張之後更容易遷移,好比開始用的是mysql作數據存儲,最後隨着數據擴大,須要把數據存儲到Mongo/ES中使用Spring Data JPA能讓你快速,更小成本的作遷移。

         (4)、mybatis的動態sql很強大,可是我以爲它不是一個團隊協做好框架。太過自由的方式並不利於代碼的質量。團隊之中sql水平真的是參差不齊的,項目大了之後不少sql的xml文件也很難維護。寫的多錯的多,這是亙古不變的道理,一個團隊中能把Java代碼寫好的人,真的不見得sql能寫好。

PS:一個完整的電商業務均可以不寫一個句SQL 使用 Spring Data全家桶作掉了,我相信只要你熟悉了Spring Data 你會喜歡他的。全部的業務均可以經過設計來避免掉複雜sql 的,若是真複雜到必需要寫巨大的sql來作業務,你真的該想一想是否是選錯了存儲服務。

五、保護你的服務

      安全是一個API穩定的前提,若是今天被別人攻擊致使服務宕機,那何談服務穩定。 jwt+spring-security 是一個很好的套件來作這件事。並且我實踐過程當中發現接口分爲三足夠使用了。不要設計的太過細緻,太過細緻的設計除了提高系統的維護複雜程度,並無什麼卵用。第一類:不須要任何認證就能夠訪問的接口。第二類:須要C端認證的的接口。第三類:管理員才能訪問的接口。用jwt+spring-security這很好實現。

六、監控你的服務

     服務快不快,穩不穩,用數聽說話才最有說服力。OpenTracing的一個實現Jaeger在分佈式應用中作鏈路追蹤中很是棒。在單應用中也不是沒有用武之地。用它來收集你接口的的調用時長,方便作優化仍是很棒的。

七、保證接口統一的輸出。異常作統一攔截。我建議每一個接口的返回都應該用同一個ResponseVo。不要把你的異常拋給前端,你給他個500他也處理不了。在他眼裏接口只有對錯。對了給數據,錯了給錯誤緣由。不要把本身都解決不了的問題拋給別人。還有真的不要把全部的代碼bug攔截成‘網絡錯誤‘。怎麼就網絡錯誤。這種’甩鍋‘的錯誤緣由你除了給本身增長排查難度。還會讓別人罵你。


屁話一大堆,該上代碼了

github.com/jarven-he/s…

一、內置了swagger來作文檔展現

二、jwt+spring-security來作安全認證。留好了認證的口子,留了個 todo 本身去接入你的帳戶系統吧

三、內部有一組API基本上是電商中商品的所有設計。看成demo來給你參照使用。

四、統一錯誤處理AOP沒放在裏面。參照本身的業務自行實現。

五、接口跨域的問題也已經處理好了

PS: 有問題歡迎關注 程序員的摸魚之道 討論

相關文章
相關標籤/搜索