公司規(guī)定所有接口都用POST請求...
最近在逛知乎的時候發(fā)現(xiàn)一個有趣的問題:公司規(guī)定所有接口都用 post 請求,這是為什么?
圖片來自 包圖網(wǎng)
看到這個問題的時候其實我也挺有感觸的,因為我也曾經(jīng)這樣問過我自己。
在上上一家公司的時候接到一個項目是從零開始搭建一個微服務(wù),當(dāng)時就有了解過接口的一些規(guī)范。
比如耳熟能詳?shù)?Restful 規(guī)范,就被應(yīng)用到這個微服務(wù)項目中。今天再次看到這個問題,我也有了一些新的理解和感觸。
臨時回顧了一下 get 與 post 的請求的一些區(qū)別:
- post 更安全(不會作為 url 的一部分,不會被緩存、保存在服務(wù)器日志、以及瀏覽器瀏覽記錄中)
- post 發(fā)送的數(shù)據(jù)更大(get 有 url 長度限制)
- post 能發(fā)送更多的數(shù)據(jù)類型(get 只能發(fā)送 ASCII 字符)
- post 比 get 慢
post 用于修改和寫入數(shù)據(jù),get 一般用于搜索排序和篩選之類的操作。
get 請求的是靜態(tài)資源,則會緩存,如果是數(shù)據(jù),則不會緩存。
查看上面的區(qū)別,就會發(fā)現(xiàn) post 在發(fā)送數(shù)據(jù)量大的請求時優(yōu)勢很顯示,get 則更適合獲取靜態(tài)資源、簡單的查詢等接口。
我個人在開發(fā)接口的時候也會注意,將簡單的查詢請求使用 get 方法,其他增、刪、改、復(fù)雜的查詢請求都可以使用 post,但不會像題主的公司一樣全部使用 post。
網(wǎng)友:程墨 Morgan
網(wǎng)友程墨 Morgan 提出如果是自己,會按照『業(yè)界最佳實踐』制定規(guī)范:
網(wǎng)友:蘇莉安
另外一個知友提出:就是為了遷就低水平不思進取的架構(gòu)師和前后端程序員們。
網(wǎng)友:大寬寬
我打算跳出技術(shù)的范疇,從 ROI 的角度討論下如果一個架構(gòu)風(fēng)格(比如 Restful)真的那么好,為啥應(yīng)用上沒有那么廣泛?
首先要明確,不管你多么喜歡技術(shù),無論是這里說的一個 http 的 method,又或者是編程語言的一些用法、架構(gòu)設(shè)計方法、甚至是 OKR 這樣的管理和溝通的方法。
這一切,都是為了滿足企業(yè)對市場的需求。簡單來說,公司給你發(fā)工資,不是為了讓你遵守規(guī)范的,而是為了能在成本可接受的情況下,讓業(yè)務(wù)落地。
而其中,一般情況下,接口的形式是個微不足道的局部問題。
對于企業(yè)來講,技術(shù)團隊要解決的更重要的問題,是理解業(yè)務(wù)模型,形成業(yè)務(wù)架構(gòu)和可以穩(wěn)定跑的系統(tǒng);是面對大量涌入用戶對系統(tǒng)可用性的要求對系統(tǒng)不會卡頓掛機的擴展性保障;是不會動不動抽瘋一下,丟條數(shù)據(jù)或者數(shù)據(jù)沖突的穩(wěn)定性要求,以及為了達成這些要求給監(jiān)控體系的各種便利。
但一定要糾結(jié)下 POST/GET,以及 Restful。好吧,Restful 能明確列出來的好處,就那么幾點(如果有疏漏的請在評論區(qū)里補充):
- 表達不同的業(yè)務(wù)動作語義:GET/POST/PATCH/PUT/DELETE……
- 表達“資源”的概念
- 利用url path,querystring,header,status code 等來表達很多接口功能
- 以上兩條可以達成一種“統(tǒng)一”的接口表達形式,以至于可以圍繞這個形式實現(xiàn)接口維護的工具,比如 swagger
- Get 資源可以利用緩存
但代價是什么?強行的統(tǒng)一,讓本來天然不是資源的業(yè)務(wù)概念也一定要強行“資源“一下,引發(fā)了更多的理解不一致和溝通困難。
當(dāng)然,事物總是和可以“抽象”一下,業(yè)務(wù)概念抽象為“資源”很多時候都是可行的。
但這這么做的收益除了證明“一個人聰明,有不錯的抽象能力“,以及“更容易利用上 swagger 一類的工具“之外,我看不到啥額外的短期或者長期收益。
亂折騰 path,querysting 等東西,讓橫切面治理抓取關(guān)鍵信息更難了。比如監(jiān)控時抓一個 path 里帶變量的 url 是非常惡心的事情。
又或者看到一個 404 的報警,卻根本搞不清楚到底是服務(wù)部署有問題;還是服務(wù)正常,但用戶不存在;又或者是用戶存在,但用戶訂單不存在。帶來的問題是運營工具編寫困難,線上問題響應(yīng)能力會被降低。
即使使用 swagger,還是需要寫說明和文檔來說明其業(yè)務(wù)語義。接口工具應(yīng)該提供的“好理解,接口改了后文檔自動生成”等好處,只有在接口反應(yīng)的資源剛好和后臺數(shù)據(jù)表/視圖能夠?qū)?yīng)上才有效。
也就是說只適合接口層級低的場景下有用,而對高層接口意義不大。結(jié)果開發(fā)者既要用 swagger 這樣的工具,同時還是要看常規(guī)文檔。本來用一套機制可以解決的問題要改成兩套。
Cache 雖好,但最怕的是管控不到位讓用戶拿到了過期數(shù)據(jù)。對于 Cache,業(yè)務(wù)上一般會區(qū)分動態(tài)接口和靜態(tài)接口。
前者默認(rèn)不應(yīng)該有 cache,所以用了 Get 之后為了防范,還得手工在大部分動態(tài)接口上加 Cache-Control:no-cache,或者動態(tài)產(chǎn)生 ETag(浪費 CPU)。而后者一般會采用 CDN,這一套針對 cache 做了很精巧的設(shè)計。
使用形式各異的 method 和 url path,querystring 上做各種奇怪的拼接,會給前端帶來巨大的困擾,因為本來一個函數(shù)調(diào)用,還得翻譯一遍,活生生的弄出來一個接口翻譯層。
妥妥的降低人效。如果是 Web,iOS,Android 三套前端,就得弄 3 個接口翻譯層。
非 GET 和 POST 之外的 method 有可能會被不恰當(dāng)?shù)木W(wǎng)關(guān)轉(zhuǎn)發(fā)規(guī)則給干掉。
為此 Restful 還是搞出了 method override 這樣的招數(shù)……所以到底適不適合,落地時聽罵聲和吵架聲就知道了。
有人舉了 Google S3 運用 Restful 接口的例子來說明其正確性。但 S3 是干什么的大家都懂,S3 天然就是用來存取“資源“的。一個工具用在了恰當(dāng)場景,當(dāng)然是“正確“的。
S3 用的好的東西,只能說明類似的阿里云 OSS,騰訊云 COS 也可以這么干。但無法證明電商業(yè)務(wù)、社交業(yè)務(wù)、I醫(yī)療業(yè)務(wù)、政企辦公協(xié)同……這些業(yè)務(wù)也適合這么干。
而作為技術(shù)負(fù)責(zé)人,如果他搞出了一套接口方案(也許其中一條就是所有 http 接口都用 post),提高了開發(fā)效率,降低了溝通成本,降低了運維和錯誤定位成本,為企業(yè)真正做到了降本增效。
把瞎折騰的成本,投入到了其他比如業(yè)務(wù)架構(gòu)設(shè)計,測試體系,線上監(jiān)控,容災(zāi)降級等領(lǐng)域上。
最終讓企業(yè)(用戶需求得到滿足,收入增加)和員工得到了收益(因為公司收入增加而漲薪)。
我會評價這樣的人為“真正懂架構(gòu),懂技術(shù),善于用技術(shù)解決實際問題。水平不知道高到哪里去了“。
如果一個技術(shù)負(fù)責(zé)人只知道遵守一個書上寫的,但從沒驗證過在自己的環(huán)境有效的方案,以至于讓企業(yè)的核心目標(biāo)無法達成。他就是趙括,該馬上卷鋪蓋卷走人。
至于我司,使用的規(guī)范是:對于動態(tài)業(yè)務(wù)接口,只有一個接口 POST /action,在 Header 里給 X-Action 給出具體的接口名稱交給網(wǎng)關(guān)路由,session 表示用戶登錄身份,以及用于推薦、防重、染色、安全用到的各種 token/簽名。
所有的業(yè)務(wù)請求參數(shù)都以 PB 編碼后放在請求體里,并和后端的 gRPC 體系銜接。接口除了防重試之外,不提供常規(guī)意義上的 Cache。
而對于靜態(tài)接口,走 CDN,做多級 Cache。該用 Get 用 Get。如果一個動態(tài)接口也想利用 http 層 Cache,可以向網(wǎng)關(guān)申請和配置。有沒有 Cache,cache 多久是網(wǎng)關(guān)和端上自己實施的,完全自己管控。
各位讀者可以參考看看,并根據(jù)自己所處的業(yè)務(wù)場景和前后端交互思考下“我們目前用的技術(shù)規(guī)范是性價比最高的嗎,是最合適的嗎?”
如果是你來設(shè)計公司的 API 規(guī)范,會規(guī)定所有接口都用 post 請求嗎,這是為什么?
來源:zhihu.com/question/336797348