你還在用 REST API 嗎?

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過 HTTP 發送數據,許多開發人員已經在用 REST 了,而 GraphQL 通常被認爲是一種代替遺留 REST API 的技術。本文將對比兩者各自的優勢、劣勢以及它們之間的差異,希望能爲你今後項目的技術選型提供幫忙。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"什麼是 REST?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"REST(Representational state transfer,表述性狀態轉移)"},{"type":"text","text":" 是一種 API 設計架構,用於通過使用一組預定義的無狀態操作(包括"},{"type":"codeinline","content":[{"type":"text","text":"GET"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"POST"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"PUT"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"DELETE"}]},{"type":"text","text":")來實現 Web 服務。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"REST 的核心思想是,通過向資源的 URL 發送請求並獲得響應(通常是 JSON,但這取決於 API)來檢索資源。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"REST 的優勢"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"REST 是 "},{"type":"text","marks":[{"type":"strong"}],"text":"可擴展的"},{"type":"text","text":",因爲它分離了客戶端和服務端,因此我們可以輕鬆擴展應用程序。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"靈活性"},{"type":"text","text":" 是使用 REST 的另一個優勢,因爲可以將其設計成處理不同類型的調用並返回不同的數據格式。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"REST 的劣勢"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"抓取過度"},{"type":"text","text":"——這是指 API 端點提供的信息比客戶端所需要的要多得多。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"抓取不足"},{"type":"text","text":"——這是指 API 端點並沒有提供所需的全部信息。因此,客戶端必鬚髮出多個請求才能獲取應用程序所需的全部內容。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"什麼是 GraphQL?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"GraphQL"},{"type":"text","text":" 是一種 API 設計架構,它採用了不同的方法,在這種方法中,所有的東西都被視爲一個表示其連接的圖。這也意味着我們可以定製我們的請求,這樣我們就可以從端點發出任何請求,並且能獲得我們所請求的任何內容,僅此而已,無需更多操作。我們傳遞查詢並得到響應。除此之外,它還允許我們將不同的實體組合到單個查詢中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"GraphQL 的優勢"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"檢索精確的數據"},{"type":"text","text":",無任何多餘數據。在 GraphQL 中,可以得到我們所請求的內容,這是一個很大的優勢。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"客戶端開發速度更快"},{"type":"text","text":"。通常,當數據需求發生變化時,我們只需修改查詢,且無需太多的變更,因此可以快速進行產品迭代。客戶端和服務端團隊都可以獨立工作,前提是他們都知道數據的結構。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"GraphQL 的劣勢"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於簡單的應用程序來說,設置類型、查詢等可能有點 "},{"type":"text","marks":[{"type":"strong"}],"text":"複雜"},{"type":"text","text":",因爲使用 REST 可以很容易地完成。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它使用的是 "},{"type":"text","marks":[{"type":"strong"}],"text":"單個端點"},{"type":"text","text":",而不是遵循 HTTP 規範進行緩存。在網絡級別進行緩存是很重要的,因爲它可以減少到服務端的流量。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"兩者對比的簡單示例"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例如,我們正在顯示用戶的供稿,其中包含用戶的帖子及其關注者的列表。在我們的例子中,我們必須顯示該帖子的作者、帖子以及該用戶的關注者。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果使用 REST,我們至少要發出 2 到 3 個請求,類似於:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"\/user\/"}]},{"type":"text","text":"以獲得用戶(作者)的詳細信息,比如名稱。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"\/user\/\/posts"}]},{"type":"text","text":"獲取該用戶發佈的帖子列表。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"\/user\/\/followers"}]},{"type":"text","text":"以獲取該用戶的關注者列表。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是在所有這些情況下,我們都過度抓取數據了。例如,在第一個請求中,我們只需要名稱,但是當我們使用這種方法時,我們將會獲取該用戶相關的所有詳細信息。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此時就是 GraphQL 顯示其強大功能的時候了。我們需要指定查詢,然後才能獲得所需的輸出。要使用 GraphQL 實現相同的效果,我們可以使用類似於這樣的查詢:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"properties"},"content":[{"type":"text","text":"query {\n User(id: '123') {\n name\n posts {\n title\n }\n followers {\n name\n }\n }\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過使用這樣的查詢,我們將能獲得具有以下屬性的 JSON 響應。簡潔明瞭,不是嗎?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"GraphQL vs REST"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"總結一下,兩者主要有如下幾個明顯的差異:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"數據抓取"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"REST 會導致抓取過度或抓取不足,而 GraphQL 則不會這樣。在 GraphQL 中,我們得到的就是我們所要求的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"對象定義(JSON 響應)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 REST 中,我們可以在後端定義對象,而在 GraphQL 中,我們則要在前端定義該對象。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"自動緩存"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"REST 能自動生效緩存,而 GraphQL 則沒有自動緩存系統,但是可以藉助 Apollo Client、Relay 等客戶端實現緩存。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"錯誤處理"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"REST 中的錯誤處理比 GraphQL 簡單得多,GraphQL 通常會給我們一個 200 OK 的狀態碼,即使已經出現錯誤了。但是,當使用 Apollo Client、Relay 等客戶端時,它也能很容易處理錯誤。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"結論"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與 REST 相比, GraphQL 當然更具優勢,但它可能並不總是最佳實踐。正如我前面所說的,是選擇 REST 還是 GraphQL,取決於我們的應用程序。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"希望本文能爲大家在未來項目的技術選型中提供幫忙。如果大家想分享自己關於 GraphQL 或 REST 的經驗,請在評論區留言,感謝您的閱讀!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文鏈接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/medium.com\/javascript-in-plain-english\/stop-using-rest-for-apis-d697727ae6dd","title":"","type":null},"content":[{"type":"text","text":"https:\/\/medium.com\/javascript-in-plain-english\/stop-using-rest-for-apis-d697727ae6dd"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章