公司規定所有接口都用 POST請求,看不起 get ?這是爲什麼?

最近在逛知乎的時候發現一個有趣的問題:《公司規定所有接口都用 post 請求,這是爲什麼?》

看到這個問題的時候其實我也挺有感觸的,因爲我也曾經這樣問過我自己。在上上一家公司的時候接到一個項目是從零開始搭建一個微服務,當時就有了解過接口的一些規範,比如耳熟能詳的 Restful 規範,就被應用到這個微服務項目中。

今天再次看到這個問題,我也有了一些新的理解和感觸,臨時回顧了一下 get 與 post 的請求的一些區別:

  • post更安全(不會作爲url的一部分,不會被緩存、保存在服務器日誌、以及瀏覽器瀏覽記錄中)
  • post發送的數據更大(get有url長度限制)
  • post能發送更多的數據類型(get只能發送ASCII字符)
  • post比get慢
  • post用於修改和寫入數據,get一般用於搜索排序和篩選之類的操作
  • get請求的是靜態資源,則會緩存,如果是數據,則不會緩存

查看上面的區別,就會發現 post 在發送數據量大的請求時優勢很顯示,get 則更適合獲取靜態資源、簡單的查詢等接口。

我個人在開發接口的時候也會注意,將簡單的查詢請求使用 get 方法,其他增、刪、改、複雜的查詢請求都可以使用 post,但不會像題主的公司一樣全部使用 post。

網友程墨 Morgan 提出如果是自己會按照『業界最佳實踐』制定規範:



程墨 Morgan
另外一個知友提出:就是爲了遷就低水平不思進取的架構師和前後端程序員們。



知友回答
大寬寬的回答:

我打算跳出技術的範疇,從 ROI 的角度討論下如果一個架構風格(比如 Restful)真的那麼好,爲啥應用上沒有那麼廣泛?

首先要明確,不管你多麼喜歡技術,無論是這裏說的一個 http 的 method,又或者是編程語言的一些用法、架構設計方法、甚至是OKR這樣的管理和溝通的方法。這一切,都是爲了滿足企業對市場的需求。簡單來說,公司給你發工資,不是爲了讓你遵守規範的,而是爲了能在成本可接受的情況下,讓業務落地。

而其中,一般情況下,接口的形式是個微不足道的局部問題。對於企業來講,技術團隊要解決的更重要的問題,是理解業務模型,形成業務架構和可以穩定跑的系統;是面對大量湧入用戶對系統可用性的要求對系統不會卡頓掛機的擴展性保障;是不會動不動抽瘋一下,丟條數據或者數據衝突的穩定性要求,以及爲了達成這些要求給監控體系的各種便利。

但一定要糾結下POST/GET,以及Restful。好吧,Restful能明確列出來的好處,就那麼幾點(如果有疏漏的請在評論區裏補充):

  • 表達不同的業務動作語義:GET/POST/PATCH/PUT/DELETE……,
  • 表達“資源”的概念利用
  • url path,querystring,header,status code等來表達很多接口功能
  • 以上兩條可以達成一種“統一”的接口表達形式,以至於可以圍繞這個形式實現接口維護的工具,比如swagger。
  • Get資源可以利用緩存

但代價是什麼?

  • 強行的統一,讓本來天然不是資源的業務概念也一定要強行“資源“一下,引發了更多的理解不一致和溝通困難。當然,事物總是和可以“抽象”一下,業務概念抽象爲“資源”很多時候都是可行的。但這這麼做的收益除了證明“一個人聰明,有不錯的抽象能力“,以及“更容易利用上swagger一類的工具“之外,我看不到啥額外的短期或者長期收益。

  • 亂折騰path,querysting等東西,讓橫切面治理抓取關鍵信息更難了。比如監控時抓一個path裏帶變量的url是非常噁心的事情。又或者看到一個404的報警,卻根本搞不清楚到底是服務部署有問題;還是服務正常,但用戶不存在;又或者是用戶存在,但用戶訂單不存在。帶來的問題是運營工具編寫困難,線上問題響應能力會被降低。

  • 即使使用swagger,還是需要寫說明和文檔來說明其業務語義。接口工具應該提供的“好理解,接口改了後文檔自動生成”等好處,只有在接口反應的資源剛好和後臺數據表/視圖能夠對應上纔有效。也就是說只適合接口層級低的場景下有用,而對高層接口意義不大。結果開發者既要用swagger這樣的工具,同時還是要看常規文檔。本來用一套機制可以解決的問題要改成兩套。

  • Cache雖好,但最怕的是管控不到位讓用戶拿到了過期數據。對於Cache,業務上一般會區分動態接口和靜態接口。前者默認不應該有cache,所以用了Get之後爲了防範,還得手工在大部分動態接口上加Cache-Control: no-cache,或者動態產生ETag(浪費CPU)。而後者一般會採用CDN,這一套針對cache做了很精巧的設計。

  • 使用形式各異的method和url path,querystring上做各種奇怪的拼接,會給前端帶來巨大的困擾,因爲本來一個函數調用,還得翻譯一遍,活生生的弄出來一個接口翻譯層。妥妥的降低人效。如果是web,iOS,Android三套前端,就得弄3個接口翻譯層。

  • 非GET和POST之外的method有可能會被不恰當的網關轉發規則給幹掉。爲此Restful還是搞出了method override這樣的招數……

所以到底適不適合,落地時聽罵聲和吵架聲就知道了。

有人舉了Google S3運用Restful接口的例子來說明其正確性。但S3是幹什麼的大家都懂,S3天然就是用來存取“資源“的。一個工具用在了恰當場景,當然是”正確“的。S3用的好的東西,只能說明類似的阿里雲OSS,騰訊雲COS也可以這麼幹。但無法證明電商業務、社交業務、I醫療業務、政企辦公協同……這些業務也適合這麼幹。

而作爲技術負責人,如果他搞出了一套接口方案(也許其中一條就是所有http接口都用post),提高了開發效率,降低了溝通成本,降低了運維和錯誤定位成本,爲企業真正做到了降本增效。把瞎折騰的成本,投入到了其他比如業務架構設計,測試體系,線上監控,容災降級等領域上。最終讓企業(用戶需求得到滿足,收入增加)和員工得到了收益(因爲公司收入增加而漲薪)。我會評價這樣的人爲“真正懂架構,懂技術,善於用技術解決實際問題。水平不知道高到哪裏去了“。

如果一個技術負責人只知道遵守一個書上寫的,但從沒驗證過在自己的環境有效的方案,以至於讓企業的核心目標無法達成。他就是趙括,該馬上捲鋪蓋捲走人。

至於我司,使用的規範是。

對於動態業務接口,只有一個接口 POST /action,在Header裏給X-Action給出具體的接口名稱交給網關路由,session表示用戶登錄身份,以及用於推薦、防重、染色、安全用到的各種token/簽名。所有的業務請求參數都以PB編碼後放在請求體裏,並和後端的gRPC體系銜接。接口除了防重試之外,不提供常規意義上的Cache。而對於靜態接口,走CDN,做多級Cache。該用Get用Get。如果一個動態接口也想利用http層Cache,可以向網關申請和配置。有沒有Cache,cache多久是網關和端上自己實施的,完全自己管控。

各位讀者可以參考看看,並根據自己所處的業務場景和前後端交互思考下“我們目前用的技術規範是性價比最高的嗎,是最合適的嗎?“

如果是你來設計公司的 API 規範,會規定所有接口都用 post 請求嗎,這是爲什麼?

原問題:zhihu.com/question/336797348

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章