前端如何调用后端接口_后端开发:如何写出可靠的接口
畢業(yè)進(jìn)入現(xiàn)在的公司已近一年,完整參與了部門新項(xiàng)目?jī)善诘拈_發(fā)上線過(guò)程,作為一名后端開發(fā),覺得最痛苦的是上線前和上線后的改 bug 階段,面對(duì)各種突如其來(lái)、莫名其妙的bug,頭昏腦漲、手忙腳亂、越改越懵,經(jīng)常導(dǎo)致實(shí)驗(yàn)式改 bug、改一個(gè) bug 又出現(xiàn)倆 bug 的之類的慘劇,我就忍不住想,為什么每次上線前都會(huì)有這么多bug呢?
前幾天還讀到一篇豆瓣文章,沒有總結(jié)的就不是經(jīng)驗(yàn),只是經(jīng)歷。程序員也不能業(yè)務(wù)來(lái)了就寫代碼,有bug了就改bug,這樣技術(shù)很難提升,也就難怪每次都會(huì)有那么多bug了。有的開發(fā)人員工作多年,接口還是時(shí)不時(shí)500,前期忙著寫代碼,后期忙著改bug,心累。
我從一期熟悉業(yè)務(wù)、框架,寫一寫邊緣接口,到二期負(fù)責(zé)一個(gè)小模塊,嘗試數(shù)據(jù)庫(kù)、程序的設(shè)計(jì),中間磕磕絆絆,昨天也順利上線,模模糊糊也感覺到了一些經(jīng)驗(yàn),于是努力總結(jié)下,雖然簡(jiǎn)單,也許能給自己和讀者一些啟發(fā)。(本文只針對(duì)初級(jí)水平,簡(jiǎn)單的bug,不涉及高并發(fā)、海量數(shù)據(jù)等復(fù)雜問(wèn)題)
一. 接口為什么出bug?
辛辛苦苦寫的接口,自己測(cè)的時(shí)候好好的,怎么別人一調(diào)就出錯(cuò)了呢??(此處應(yīng)有表情包,請(qǐng)自行腦補(bǔ))當(dāng)然可能是運(yùn)行環(huán)境的問(wèn)題,不過(guò)程序統(tǒng)一部署在服務(wù)器上,這一般是架構(gòu)師或者運(yùn)維負(fù)責(zé)的工作,至于編程語(yǔ)言或者操作系統(tǒng)的問(wèn)題,也通通不在今天考慮范圍內(nèi),今天,我們只考慮自己寫出的bug。
事實(shí)上,運(yùn)行中的程序所涉及的,無(wú)非三樣:資源(cpu、內(nèi)存等)+ 算法(程序運(yùn)行流程)+ 數(shù)據(jù)(用戶輸入、數(shù)據(jù)庫(kù)、第三方接口等)。通常我們認(rèn)為資源是可靠的,出現(xiàn)bug主要是由于算法的不可靠或者數(shù)據(jù)的異常。
更進(jìn)一步,機(jī)器嚴(yán)格按照0/1執(zhí)行指令,算法上一次執(zhí)行正常,為什么這一次會(huì)失敗?本質(zhì)上還是因?yàn)閿?shù)據(jù)變了,而算法沒能覆蓋此情況,因此,要想保證接口的穩(wěn)定,主要從兩方面考慮:保證數(shù)據(jù)的可靠性、算法的健壯性,而算法的健壯性也就是考慮到數(shù)據(jù)的各種情況,兩者密不可分。
二. 如何寫出bug更少的接口?
如前分析,數(shù)據(jù)的變化是接口bug最常見、本質(zhì)的原因。而其中,用戶輸入又是數(shù)據(jù)變化最主要的原因。而程序必然要有用戶輸入,否則毫無(wú)意義。
編程界有句名言:永遠(yuǎn)不要相信用戶輸入。你永遠(yuǎn)不知道,用戶會(huì)在一個(gè)期待姓名的輸入框里都輸入些什么。不要因?yàn)榍岸俗隽诉^(guò)濾你就放心,一方面是用戶可能會(huì)使用爬蟲等手段直接訪問(wèn)你的接口,另一方面,前端也是你的用戶,溝通也存在誤差,前端可能會(huì)使用錯(cuò)誤的方式調(diào)用你的接口,而這種錯(cuò)誤可能會(huì)更加隱蔽。
第一條建議:嚴(yán)格校驗(yàn)用戶的輸入,包括格式、內(nèi)容。
我知道很多人都懶得去逐條檢驗(yàn)用戶輸入,覺得只要功能正常就ok了,但是,這經(jīng)常會(huì)導(dǎo)致后期改bug時(shí)投入更多的經(jīng)歷。經(jīng)常測(cè)試提了bug,你查來(lái)查去,發(fā)現(xiàn)是前端傳錯(cuò)了參數(shù),或者沒有合理限制用戶輸入,當(dāng)然你可以很剛,讓前端去改,但這個(gè)過(guò)程已經(jīng)浪費(fèi)了你大量的時(shí)間精力,還不如一開始自己做好檢驗(yàn),返回合適的錯(cuò)誤消息,會(huì)為你后期節(jié)省大量的精力。
對(duì)于PHP等動(dòng)態(tài)語(yǔ)言,尤其如此,例如我們使用Laravel框架,我會(huì)在所有接口入口處,首先使用$request->validate()檢驗(yàn)所有輸入數(shù)據(jù)的格式,如有必要,還會(huì)寫代碼進(jìn)一步校驗(yàn)輸入內(nèi)容,比如時(shí)間范圍、請(qǐng)求數(shù)據(jù)是否有效等等。
第二條建議:考慮用戶的騷操作,重復(fù)提交、延時(shí)提交
重復(fù)提交應(yīng)該是大多數(shù)后端都能想到的情況,也就是接口的冪等性,有些資源只能操作一次,必須進(jìn)行校驗(yàn),其實(shí)不僅是重復(fù)提交,還包括同一事件被兩人重復(fù)處理的情況。
而對(duì)于延時(shí)提交,其實(shí)是測(cè)試給我提bug后我才意識(shí)到的問(wèn)題模式。例如我們通過(guò)get接口返回給用戶某種資源,用戶可以通過(guò)post接口回傳資源id并提交修改,由于是自己的get接口返回的,我們可能想著只驗(yàn)證id合法就行了,看似形成嚴(yán)格閉環(huán),但如果用戶停留在此頁(yè)面延時(shí)提交,則可能在此期間資源過(guò)期,或者資源已被他人修改,而改用戶也成功修改的bug。其實(shí)進(jìn)一步思考,你會(huì)發(fā)現(xiàn),這跟高并發(fā)情景下的資源失效有異曲同工之處。
第三條建議:檢驗(yàn)數(shù)據(jù)庫(kù)、第三方接口的返回?cái)?shù)據(jù)
除了用戶輸入,常見的數(shù)據(jù)來(lái)源還有數(shù)據(jù)庫(kù)、第三方接口。相對(duì)而言,這些數(shù)據(jù)接口會(huì)可靠的多,而且內(nèi)容格式也更規(guī)范。不過(guò)為了接口的穩(wěn)定性,最好也做一些檢驗(yàn)。如常見的數(shù)據(jù)為空的情況,就要及時(shí)中止程序執(zhí)行并拋出合適的信息。
對(duì)了,對(duì)于數(shù)據(jù)庫(kù),我還遇到過(guò)bug,就是主從延遲導(dǎo)致的數(shù)據(jù)更新問(wèn)題,由于經(jīng)驗(yàn)尚淺,這類問(wèn)題不很擅長(zhǎng),就不再寫。
第四條建議:程序算法盡可能覆蓋異常情況
這條實(shí)際上是對(duì)前三條的補(bǔ)充,有些不合法的用戶輸入你可以直接中止程序并返回錯(cuò)誤信息,但有些情況可能需要程序繼續(xù)運(yùn)行,進(jìn)行特殊處理,這些情況你在程序設(shè)計(jì)之初應(yīng)該盡量考慮周全,后期bug會(huì)少很多,也更容易維護(hù)。
三. 如何寫出更高效的接口
最后,再寫一點(diǎn)點(diǎn)關(guān)于關(guān)于接口效率、代碼質(zhì)量的思考。
以我有限的經(jīng)歷來(lái)看,接口耗時(shí)長(zhǎng)基本都是因?yàn)閿?shù)據(jù)庫(kù)操作不合理,我們大多數(shù)的業(yè)務(wù)代碼并不會(huì)有性能問(wèn)題。我見過(guò)不少在for循環(huán)里查詢數(shù)據(jù)庫(kù)的代碼,一定要避免,我們可以先一次性取出所有數(shù)據(jù),然后逐個(gè)去處理。例如我們會(huì)在框架層記錄所有數(shù)據(jù)庫(kù)操作,調(diào)試接口時(shí)即可看到所有數(shù)據(jù)庫(kù)操作以及相應(yīng)耗時(shí),該合并的查詢要合并,該優(yōu)化的耗時(shí)查詢相應(yīng)去優(yōu)化。
2. 合理使用Exception,日志
這條主要針對(duì)php語(yǔ)言,由于歷史原因,我看到不少代碼靠return中止程序并傳遞錯(cuò)誤信息,這樣在代碼復(fù)雜、調(diào)用層次深了以后極難維護(hù),遠(yuǎn)沒有Exception機(jī)制直觀方便。還有,重要信息一定要寫日志,便于后期發(fā)現(xiàn)問(wèn)題及調(diào)試,也可用來(lái)自證清白。
3. 代碼要合理劃分、抽象
不要復(fù)制粘貼代碼,重復(fù)的功能要獨(dú)立出來(lái);設(shè)計(jì)時(shí)要合理考慮需求變更、擴(kuò)展;寫小而專注的函數(shù),不要把復(fù)雜功能一坨實(shí)現(xiàn);這樣寫的代碼才易于修改、測(cè)試以及擴(kuò)展。這塊我做的也不好,上線后看自己的代碼都是一坨一坨,難以維護(hù),接下來(lái)還要多思考,多實(shí)踐。
四. 結(jié)束語(yǔ)
祝大家寫的代碼都沒有bug!
總結(jié)
以上是生活随笔為你收集整理的前端如何调用后端接口_后端开发:如何写出可靠的接口的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: CreateRemoteThread函数
- 下一篇: linux系统运维指南 pdf_linu