Re: [討論] API沒資料,回200還是404比較好

看板Soft_Job作者 (迅雷不及掩耳盜鈴)時間1年前 (2022/06/25 23:48), 編輯推噓84(84012)
留言96則, 84人參與, 1年前最新討論串7/7 (看更多)
這篇就不以引述的方式回覆了,因為算是對 後續其他人不論在推文中或是回文中的內容 回覆,另外也是針對我自己在前一篇文章中 沒有提到的部分進行說明。 (1) 敘述問題與回答問題 我不知道這裡有多少人上過 jserv的課,如 果有的話,他會頻頻強調不要「舉燭」。從 推文和回文中可以看到,其實不論是發文者 還是回答者,似乎並沒有很正視這個問題… … 回到最一開始的問題: 「API 沒資料要回傳 200 還是 404?」 ‧什麼樣的 API 呢? ‧什麼樣的場景下設計的呢? ‧什麼樣的狀況叫做沒資料? ‧有沒有基於什麼規範或風格? ‧調用的人是誰? ‧你怎麼想的呢? 如果沒有敘述清楚,要人怎麼回答呢?我想 分享一下兩段文字: https://i.imgur.com/JWMQJjn.png
[來源] http://hhp.li/4aq287 https://i.imgur.com/KPxidqA.png
[來源] http://hhp.li/43pp7h 你真的想要得到的答案是這樣的嗎? 「公司前輩這樣做就這樣做啦!」 「為了方便,問就是 404 一把梭!」 這樣可以得到什麼成長嗎?你認為去有規模 的公司面試問到這樣的問題時,用這樣的回 答可以拿到 Strong Hire?老實說,這樣的 提問方式和不明就理的回答方式,只會讓社 群的風氣變得越來越糟。 (2) 不是只有 REST 一種設計風格 雖然在前一篇文章中以及推文中,我主要都 以 REST 風格的敘述為主,但那個前提是我 認為那樣的問題敘述下,原 po 的問題是在 下述兩種不同情境下,採用 REST 風格而有 所誤解: --- [GET] /users [GET] /users/<USERNAME> 上述沒有資料的情形會有兩種: ‧在 users 中沒有任何 user →狀態 200 並返回 [] 於 body ‧名稱為 <USERNAME> 的 user 不存在 →狀態 404 視情況返回 body --- 但這並不代表實際開發就只有 REST 這一種 以資源為導向的風格,還有 RPC這種以方法 為導向的風格,比如早期可以見到 SOAP 的 身影,近期為了更好地適應某些場景以及發 揮 HTTP2 的優勢,還可以選擇 GraphQL 或 是 gRPC 。如果是區塊鏈的開發者,應該更 常透過 JSON-RPC 協議讀取數據。 比如以登入、搜尋等業務,就不是很好將這 兩個操作抽象為資源,並以 REST 實作。當 然要實作也並無不可,比如常見地將登入行 為改以 session 資源的創建、查詢與刪除… 這很要求開發者的抽象能力,並且對於複雜 業務來說侷限性很大;或者當我只需要文章 的標題與發表時間,以 REST 實作就會拿取 冗贅的資料。 當然,他們都各有優缺,也需要開發人員去 做取捨的。我建議拿上述關鍵字去搜一下差 異,包含 payload和調用方法等;想再了解 更多可以參考各個團隊的技術文章,我會整 裡幾篇放在最後的參考資料中。 (3) 考量資源限制與團隊協作 後面的回覆中,有板友提及了傾向於使用特 定狀態碼是為了方便前端介接;也有板友提 及企業內部設備會攔截特定狀態碼。這些的 確都是實務上的限制與考量,為了讓開發順 暢必須要溝通與協調的,有時候為了時程和 和外部限制(比如客戶其實沒這麼聰明又要 求很多),當然是以能跑為第一前提…… 不過這點其實我想稍微糾正一下,但必須先 說這不是所有團隊都適用,就是「不能只有 自己爽」這件事情,有時候還請三思一下是 誰在自己爽。 --- 前提狀況如下: ‧以 REST 風格設計 ‧接口 [GET] /users/<USERNAME> ‧<USERNAME> 不存在時返回 200 而非 404 好的,前端可以快速知道今天是後端的接口 壞掉還是正常;但是出問題時,後端要怎麼 判斷是不是參數錯誤呢? DevOps/SRE 負責 監控狀態,然後一片都 200看起來很正常, 但是使用者說資料都空的,怎麼排查? 透過正確的 HTTP Status Code 可以很快地 讓後端和 DevOps/SRE 定位原因,如果都是 200 的話,需要每一個狀態都打開查看內容 才能判斷,這真的是個好方式嗎? 在後端看來,他依照 REST 風格和 HTTP 規 範設計,是他為了自己爽嗎? --- 即使進到 exception也能夠根據狀態碼再去 處理,而狀態碼 404 也能夠攜帶 body而不 是就沒有了內容;至於前端的請求函數庫, 以 axios 來說可以自定義 validateStatus 調整 reject 的範圍吧? 今天前端會呼叫 API有八成的狀況是採取了 AJAX 方式,獲取資料於頁面上渲染,如果 能夠接受圖片、影片也是以 URI的方式鑲嵌 在你的 HTML 中,實際上被渲染出來也是由 瀏覽器對 URI發送請求獲取資源,取得後再 渲染在頁面上,圖片網址錯誤無法訪問時, 對 Nginx/Apache 來說也是返回 404 呀! 如果是 JSON 返回一項資源,比如文章內容 或使用者資訊時,這時候網址錯誤時返回同 樣的 404為什麼就這麼難以接受呢? > 我從 /users/posts 拿到了 pid = 256 > 但是 /posts/256 卻 404 > 權限不夠或是真的沒有這篇文章 > 回去檢查為什麼 /users/posts 吐出 256 (抱歉上述是以網頁應用程式為敘述,我知 道對於移動端開發來說,Android 跟 Swift 下的一些 HTTP 請求框架也有問題,但我不 熟,就再請熟悉的板友幫忙補充了…) 另外 REST 風格真的不善於處理混合多種資 源的狀況,交給 GraphQL 處理會爽很多… (4) 前端頁面?API? 以 GitHub 來說,訪問以下頁面: https://github.com/love99067333/ https://github.com/search?q=3123sadq 上述兩個網址都是交由伺服器端渲染返回, 並非由 AJAX 呼叫他們自家的 REST API 獲 取資料再渲染於頁面中。以前一篇所說明的 REST 風格設計來說,此時的「頁面」就是 「資源」,分別請求的是「使用者頁面」和 「搜尋 3123sadq 的結果頁面」。 他也符合 RFC 723x 中對於狀態碼的陳述, 所以對於有資源且存在的使用者頁面返回狀 態碼 200;而對搜尋結果頁面也是 200;而 對於使用者不存在或不願顯示的私密倉庫, 就會是 404 了。 --- 如果是 GitHub 對於 search 的 REST 實作 ,可以參考這裡: https://docs.github.com/en/rest/search BASE_URL 是 https://api.github.com/ 你會發現: [GET] /search → 404 (沒有 search 這個資源) [GET] /search/code → 422 (有 search/code 這種資源,但可能參數不足) [GET] /search/code?q=repo:octocat/Spoon-Knife+css → 200 (有 search/code 這種資源,而且參數正確) [GET] /search/cars → 404 (沒有 /search/cars 這種資源) --- 這時候不應該以資料夾路徑的角度去看待這 個資源,上述 REST 實作時,他不是以檔案 系統的方式來呈現資源的;也不是以頁面型 態呈現資源的。 老實說,他們家的 REST API 對我來說堪稱 楷模,因為把很多資源的抽象都做得非常優 秀……但在下面這篇文章中,也坦言存在缺 點並增添了 GraphQL API: http://hhp.li/4anhqf (5) 參考資料 ‧API Design Guide (Google Cloud APIs) http://hhp.li/4afqel 同時考慮了 REST API 和 RPC API 設計 對於常用的 Standard Methods 多採用了 REST 風格,而 Custom Methods 多採用  RPC 風格。 ‧Best Practices for Designing a Pragmatic RESTful API http://hhp.li/4a5n57 應該是多數 REST 使用者都曾經看過的最 佳實踐文章 ‧訪問遠程服務(鳳凰架構) http://hhp.li/4a43xw 中國一本開源的架構著作,作者是 Java 知名書籍作者,這一章節很詳細地介紹了 REST 和其優缺點 ‧一把梭:REST API 全用 POST http://hhp.li/4685dk ‧A preview of the new Dropbox API v2 http://hhp.li/4a8xqy 簡化 HTTP 使用多採 POST 請求,並簡化 錯誤代碼的使用,採 RPC-Style 設計 (6) 後記 還是要再說一次,在新創團隊和開發資源有 限的小公司中,上面提到的東西都不一定適 用…… 不可能期待一間只有三人的新創還要搞上各 種測試跟各種優化還要部署 CI/CD 吧? 但 沒辦法去到這些公司體驗文化的話,從書上 和這些大廠的技術文章來吸收跟思考,是可 以做的(當然,他們內部也可能有例外跟分 歧) 說真的這個問題可以展開來說的東西太多了 ,包括瀏覽器在輸入一個網址後會經歷哪些 過程和行為,還有網頁前後端的開發…今天 你是不是走前後端分離架構;如果純粹由伺 服器渲染,還要再分中間有沒有微服務或中 間件處理,或者後端直接訪問資料庫塞資料 給模板返回就好;是否一定要在 HTTP 協議 實現你的 API?甚至是前面有人提到的狀態 碼進異常,如果前端後端都不想要修改,有 沒有什麼處理的方式? 前陣子那串「對技術沒熱情是不是不適合這 行?」應該許多人都還記憶猶新,藉著這串 再問問文章一開始的問題: ‧如果是 Junior 的開發者,那樣的發問方  式,真的能得到解答? ‧你不追問不細問,有多少人願意主動發現 你沒問出的問題? ‧沒人回答你,你就不找答案了嗎?有人回 答你,你就直接接受了嗎? ‧如果是 Senior 的開發者,對於提問時要 不要去挖掘後面的問題?要挖到什麼程度 ? -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.82.214.46 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1656172096.A.5AE.html

06/25 23:53, 1年前 , 1F
優文推,學到不少,謝謝
06/25 23:53, 1F

06/26 00:13, 1年前 , 2F
06/26 00:13, 2F

06/26 00:51, 1年前 , 3F
06/26 00:51, 3F

06/26 00:53, 1年前 , 4F
06/26 00:53, 4F

06/26 01:33, 1年前 , 5F
06/26 01:33, 5F

06/26 01:47, 1年前 , 6F
06/26 01:47, 6F

06/26 01:56, 1年前 , 7F
感謝優文
06/26 01:56, 7F

06/26 06:52, 1年前 , 8F
推問問題的方式
06/26 06:52, 8F

06/26 06:57, 1年前 , 9F
11
06/26 06:57, 9F

06/26 08:54, 1年前 , 10F
優文
06/26 08:54, 10F

06/26 09:46, 1年前 , 11F
真是優文…大推
06/26 09:46, 11F

06/26 09:57, 1年前 , 12F
推, It depends <- 這一句很有用
06/26 09:57, 12F

06/26 10:00, 1年前 , 13F
推推!
06/26 10:00, 13F

06/26 10:16, 1年前 , 14F
06/26 10:16, 14F

06/26 10:17, 1年前 , 15F
06/26 10:17, 15F

06/26 10:31, 1年前 , 16F
優文推
06/26 10:31, 16F

06/26 11:10, 1年前 , 17F
推第一點跟那兩張圖 QQ
06/26 11:10, 17F

06/26 11:18, 1年前 , 18F
這種思維很棒,透過問自己各種問題,考慮自己所在環
06/26 11:18, 18F

06/26 11:18, 1年前 , 19F
境的狀況,釐清自己到底在做什麼,才開始蒐集資料,
06/26 11:18, 19F

06/26 11:18, 1年前 , 20F
參考別人作法,解決問題。有時候直接想解決問題忽略
06/26 11:18, 20F

06/26 11:18, 1年前 , 21F
掉前提,也是我常犯的毛病,感謝文章給我的提醒
06/26 11:18, 21F

06/26 12:32, 1年前 , 22F
感謝 舒服
06/26 12:32, 22F

06/26 12:54, 1年前 , 23F
不過新創那段,剛巧我目前在新創,工程最近剛由 2 人增
06/26 12:54, 23F

06/26 12:55, 1年前 , 24F
加到 3 人,倒是有 Unit/Api/E2E 測試,及 push 後自動
06/26 12:55, 24F

06/26 12:56, 1年前 , 25F
測試與部署,不過測試只針對重點,覆蓋率極低 XDD
06/26 12:56, 25F

06/26 13:54, 1年前 , 26F
06/26 13:54, 26F

06/26 14:02, 1年前 , 27F
06/26 14:02, 27F

06/26 14:10, 1年前 , 28F
06/26 14:10, 28F

06/26 14:25, 1年前 , 29F
我是覺得"問題"本身也可以不斷refine XD
06/26 14:25, 29F

06/26 14:32, 1年前 , 30F
06/26 14:32, 30F

06/26 14:34, 1年前 , 31F
06/26 14:34, 31F

06/26 15:02, 1年前 , 32F
06/26 15:02, 32F

06/26 15:19, 1年前 , 33F
06/26 15:19, 33F

06/26 15:42, 1年前 , 34F
感謝分享
06/26 15:42, 34F

06/26 15:57, 1年前 , 35F
06/26 15:57, 35F

06/26 16:28, 1年前 , 36F
感謝這串讓我知道很多 IT 不懂 Rest 也在寫 API
06/26 16:28, 36F

06/26 16:44, 1年前 , 37F
測試測到重點其實也比覆蓋率重要呀
06/26 16:44, 37F

06/26 17:03, 1年前 , 38F
06/26 17:03, 38F

06/26 17:04, 1年前 , 39F
非常完整
06/26 17:04, 39F

06/26 17:10, 1年前 , 40F
06/26 17:10, 40F

06/26 17:13, 1年前 , 41F
你是不是吃到jserv 口水,回文的style 這麼像
06/26 17:13, 41F

06/26 17:34, 1年前 , 42F
所以有人才會說提出夠好的問題 答案也出來一半了 就是這個
06/26 17:34, 42F

06/26 17:34, 1年前 , 43F
意思 「提問」是科學精神的重要一環啊 工程師們
06/26 17:34, 43F

06/26 18:09, 1年前 , 44F
推,整篇的回答很有條理且易理解
06/26 18:09, 44F

06/26 18:46, 1年前 , 45F
06/26 18:46, 45F

06/26 19:18, 1年前 , 46F
問問題是個學問 前陣子也看到stack overflow神人
06/26 19:18, 46F

06/26 19:18, 1年前 , 47F
也有寫書說 怎麼樣問問題最合適(就是辣個C#神人)
06/26 19:18, 47F

06/26 19:18, 1年前 , 48F
他寫的code如果編譯不過 編譯器要道歉的辣個人
06/26 19:18, 48F

06/26 19:32, 1年前 , 49F
推推Hsins大,回答得好完整
06/26 19:32, 49F

06/26 20:15, 1年前 , 50F
06/26 20:15, 50F

06/26 21:10, 1年前 , 51F
推詳細補充
06/26 21:10, 51F

06/26 21:20, 1年前 , 52F
好文必須推
06/26 21:20, 52F

06/26 22:08, 1年前 , 53F
優文推
06/26 22:08, 53F

06/26 23:25, 1年前 , 54F
推,真心感謝
06/26 23:25, 54F

06/26 23:36, 1年前 , 55F
好文推
06/26 23:36, 55F

06/26 23:52, 1年前 , 56F
這問題本來就跟實際的狀況有關
06/26 23:52, 56F

06/26 23:52, 1年前 , 57F
原po沒講的大家當然各自發揮XD
06/26 23:52, 57F

06/27 00:46, 1年前 , 58F
06/27 00:46, 58F

06/27 01:29, 1年前 , 59F
PTT充滿大神
06/27 01:29, 59F

06/27 07:20, 1年前 , 60F
06/27 07:20, 60F

06/27 07:32, 1年前 , 61F
推!好文
06/27 07:32, 61F

06/27 08:25, 1年前 , 62F
推好文,前面的提問思維,和後面的style分析都很值得思
06/27 08:25, 62F

06/27 08:25, 1年前 , 63F
考,尤其開頭的提問思維讓我想到經典的客戶需求鞦韆漫畫
06/27 08:25, 63F

06/27 09:18, 1年前 , 64F
推,這才是思考方式。
06/27 09:18, 64F

06/27 10:08, 1年前 , 65F
推,受益良多
06/27 10:08, 65F

06/27 10:45, 1年前 , 66F
好文不M嗎?
06/27 10:45, 66F

06/27 12:19, 1年前 , 67F
06/27 12:19, 67F

06/27 12:20, 1年前 , 68F
優質好文!
06/27 12:20, 68F

06/27 12:41, 1年前 , 69F
06/27 12:41, 69F

06/27 14:30, 1年前 , 70F
06/27 14:30, 70F

06/27 15:57, 1年前 , 71F
06/27 15:57, 71F

06/27 17:15, 1年前 , 72F
好扯,太精彩了吧,開頭分享的文章也很具有啟發性
06/27 17:15, 72F

06/27 23:14, 1年前 , 73F
今年跳槽Amazon就是香 香爆
06/27 23:14, 73F

06/27 23:22, 1年前 , 74F
06/27 23:22, 74F

06/27 23:51, 1年前 , 75F
推,謝謝
06/27 23:51, 75F

06/27 23:59, 1年前 , 76F
06/27 23:59, 76F

06/28 00:51, 1年前 , 77F
推。 小瑕疵 Android <==> iOS; Kotlin <==> Swift
06/28 00:51, 77F

06/28 01:04, 1年前 , 78F
06/28 01:04, 78F

06/28 02:16, 1年前 , 79F
06/28 02:16, 79F

06/28 04:24, 1年前 , 80F
安全性我一律回答404
06/28 04:24, 80F

06/28 04:26, 1年前 , 81F
只有debug才開 return200 加 debug訊息
06/28 04:26, 81F

06/28 08:29, 1年前 , 82F
推一個,帶出很多觀點
06/28 08:29, 82F

06/28 08:51, 1年前 , 83F
06/28 08:51, 83F

06/28 10:14, 1年前 , 84F
推 謝謝學到了
06/28 10:14, 84F

06/28 12:32, 1年前 , 85F
06/28 12:32, 85F

06/28 17:42, 1年前 , 86F
06/28 17:42, 86F

06/29 10:32, 1年前 , 87F
完全沒想到 DevOps/SRE 的觀點,404確實是很好判斷的依據
06/29 10:32, 87F

06/29 15:05, 1年前 , 88F
06/29 15:05, 88F

06/30 00:03, 1年前 , 89F
06/30 00:03, 89F

07/01 02:09, 1年前 , 90F
這一串只推這一篇 見解卓越且點出正確的思考方向
07/01 02:09, 90F

07/01 13:03, 1年前 , 91F
好文 推
07/01 13:03, 91F

07/01 19:26, 1年前 , 92F
推推
07/01 19:26, 92F

07/02 01:32, 1年前 , 93F
07/02 01:32, 93F

07/02 15:09, 1年前 , 94F
完整優文推
07/02 15:09, 94F

07/02 18:33, 1年前 , 95F
07/02 18:33, 95F

07/04 09:15, 1年前 , 96F
優質文推推
07/04 09:15, 96F
文章代碼(AID): #1Yjov0Mk (Soft_Job)
討論串 (同標題文章)
文章代碼(AID): #1Yjov0Mk (Soft_Job)