/users/:userName/articles/:articleId

關于這個:

/comments/:commentId
/articles/:articleId

采用這種方法的主要原因是可讀性;嵌套資源 URL 可以傳達一個資源屬于另一個資源的信息。它呈現出一種層次關系,就像文件系統中的目錄一樣。

這些 URL 傳達的關系含義較少:

/books/:bookId
/rating/:ratingId

比這些 URL:

/books/:bookId
/books/:bookId/ratings/:ratingId

我們可以直接看到我們請求的評分屬于某本特定的書。在很多情況下,這可以使調試更容易。

之所以說是層次關系,是因為底層數據模型不一定是層次化的。例如,在 GitHub 上,一個用戶可以為多個存儲庫貢獻代碼,而一個存儲庫可以有來自不同用戶的貢獻。這是一種多對多關系。

/users/:userName/repos
/repos/:repoName/users

如果您只知道其中一個端點,那么它可能看起來是一對多的關系。

其他更技術性的原因是嵌套資源的相對 ID上下文。

例如,房子有門牌號,但這些門牌號只與它們所屬的街道有關。如果你知道房子的門牌號是 42,但你不記得街道,那么這對你沒有多大幫助。

/street/:streetName/house/:houseNumber

另一個例子是文件系統中的文件名。如果數百個不同目錄中有數百個文件以同樣的名字命名,那么僅僅知道我們的文件叫什么名字是沒有用的。

/home/kay/Development/project-a/README.md
/home/kay/Development/project-b/README.md

如果我們使用關系數據庫,我們通常對所有數據記錄都有唯一的鍵,但正如我們所見,對于其他類型的數據存儲(如文件系統),情況不一定如此。

嵌套 URL 也很容易操作。如果 URL 中編碼了層次結構,我們可以刪除 URL 的部分內容以向上爬升此層次結構。這使得帶有嵌套資源的 API 導航變得相當簡單。

總而言之,我們希望使用嵌套資源來提高可讀性,進而改善開發人員體驗,有時我們甚至必須使用它們,因為數據源不提供僅通過其 ID 來識別嵌套資源的方法

缺點

現在我們討論了為什么應該使用嵌套的原因,討論另一方面也很重要:為什么我們不應該嵌套我們的資源?

雖然筑巢有時是必要的并且無法避免,但它通常是一個我們應該牢記的特定成本或危險的選擇。

讓我們逐一看一下。

可能很長的 URL

我們之前了解到嵌套資源可以使我們的 URL 更具可讀性,但這并不是萬無一失的。

特別是在資源之間存在多種關系的相當復雜的系統中,嵌套方法可能會導致相當長且復雜的 URL。

/customers/:customerId/projects/:projectId/orders/:orderId/lines/:lineId

如果我們使用長字符串作為 ID,這個問題可能會變得更加嚴重:

/customers/8a007b15-1f39-45cd-afaf-fa6177ed1c3b/projects/b3f022a4-2970-4840-b9bb-3d14709c9d2a/orders/af6c1308-613f-40ff-9133-a6b993249c88/lines/3f16dca9-870e-4692-be2a-ea6d883b9dfd

因此,當我們開始沿著這條路走下去時,我們應該有時退后一步,看看我們是否仍然能夠實現提高可讀性的目標。

經驗法則是最大嵌套深度為 2。有時深度為 3 也是可以的。例如,如果我們的 ID 很短且易于閱讀。

/author/kay-ploesser/book/react-from-zero/review/23

冗余端點

一般來說,使用嵌套資源不如僅使用根資源那么靈活。

例如,如果我們有多對多關系。存儲庫有多個貢獻者,但每個用戶也可以為各種存儲庫做出貢獻。

如果我們想通過嵌套資源實現這一點,我們必須為這種關系單獨創建兩個端點

/user/:userName/repositories
/repositories/:repositoryName/contributors

如果我們想在不嵌套的情況下實現這一點,我們可以為貢獻定義一個根資源,該資源還允許在其 URL 中使用過濾參數。

/contributions?userName=:userName&repositoryName=:repositoryName

參數是可選的,所以我們也可以用它來獲取所有貢獻,并且我們可以用PUTPOST來改變和創建關系。

雖然這似乎不是一對多關系的問題,其中關系的一部分不能有多個連接,但我們仍然可以在某個時候搜索嵌套資源在其父資源中的所有記錄。

因此,當有這個端點時:

/mothers/:motherName/children

我們可能仍然想獲取所有母親的所有孩子,并為此創建一個新的端點

/children

冗余端點也會增加我們的 API 的表面,雖然資源關系中更易讀的 URL 對開發人員體驗來說是一件好事,但大量的端點卻不是。

多個端點增加了 API 所有者記錄整個過程的努力,并使新客戶的入職變得更加麻煩。

返回相同表示的多個端點也可能導致緩存問題,并可能違反RESTful API 設計的核心原則之一。

這個問題可以通過 HTTP 重定向來解決,因此所有表示都從中央根資源返回并可以緩存,但仍然需要代碼來實現這一點。

它還可能違反另一個核心原則,即統一接口。

當客戶端持有資源的表示(包括附加的任何元數據)時,它就擁有足夠的信息來修改或刪除服務器上的資源,前提是它有這樣做的權限。

如果表示不包含有關嵌套的信息,并且我們沒有根資源來直接訪問它;我們就無法創建、更新或刪除它。

多個數據庫查詢

如果我們向下遍歷關系圖而不是使用一個唯一標識符(如果存在)來從資源中檢索表示,則我們需要檢查 URL 中實現的關系是否成立。

以獲取嵌套評論為例

/blogs/X/articles/Y/comments/Z

獲取所有博客所有文章的所有評論也是一個問題。

  1. 查詢所有博客
  2. 查詢每個博客的每篇文章
  3. 查詢每篇文章的每條評論

此 API 設計給我們帶來了N+1 查詢問題的巨大困擾。

如果我們只有評論的根資源,我們可以查詢它并在需要時添加一些過濾參數。如果評論具有全局唯一 ID,我們可以直接查詢它們。

/comments/Z
/comments?before=A&after=B

安全

如果我們共享資源鏈接,則 URL 內編碼的所有數據都可能會暴露給第三方,即使他們無權從我們的 API 請求表示。

當在互聯網上通過 HTTP 請求任何內容時,中間件都會記錄 URL,因此甚至不必在社交媒體或類似媒體上主動分享鏈接。

例如此圖片鏈接:

/users/:userName/images/:imageId

如果我們將其分享到某個地方,我們就會知道我們有一個具有特定名稱的用戶,并且他們在我們的服務上上傳了圖像。

如果圖像鏈接是根資源,則不會出現此類信息。

/images/:imageId

更改 URL

如果我們的關系發生變化,它們編碼的 URL 就不再穩定。

有時這可能很有用,但更多的時候我們希望保留我們的 URL,以便舊鏈接不會停止工作。

例如,這種所有者-產品關系:

/owners/kay/products/1234
/owners/xing/products/1234

如果該產品可以作為根資源訪問,那么誰擁有它就無關緊要了。

/products/1234

正如我之前提到的,如果關系經常發生變化,我們也可以考慮將關系本身視為一種資源。

/posessions?owner=kay&product=1234

通過這種方法,我們可以通過一個端點改變關系,但通過不受此改變影響的自己的根資源直接鏈接我們的其他資源。

總結

那么這一切的啟示是什么呢?

我們是否應該嵌套我們的資源?

有時這是無法避免的,因為數據源根本沒有給我們任何其他選擇,但如果我們有選擇,我們應該考慮所有的利弊。

如果數據是嚴格分層的,嵌套不是太深,并且關系不會經常更改,我會使用嵌套資源。

與開發人員體驗方面的優勢相比,這些缺點并不算太大。

如果數據容易發生關系變化或者一開始就有相當復雜的關系,那么維護根資源甚至考慮完全不同的方法(如 GraphQL)會更容易。

更多的端點,以及嵌套場景所暗示的更復雜的端點意味著需要編寫更多的代碼和文檔。這不會引起技能或專業知識方面的可行性問題,而往往只是開發和維護成本的問題。因此,即使我們知道如何做,并且安全性或可緩存性不是問題,我們也必須問自己這是否能給我們帶來任何競爭優勢。

原文鏈接:REST API Design Best Practices for Sub and Nested Resources

熱門推薦
一個賬號試用1000+ API
助力AI無縫鏈接物理世界 · 無需多次注冊
3000+提示詞助力AI大模型
和專業工程師共享工作效率翻倍的秘密
熱門推薦
一個賬號試用1000+ API
助力AI無縫鏈接物理世界 · 無需多次注冊
返回頂部
上一篇
REST API 設計參數和查詢字符串使用的最佳實踐
下一篇
精通API規范:構建明確指導和預期的指南
国内精品久久久久影院日本,日本中文字幕视频,99久久精品99999久久,又粗又大又黄又硬又爽毛片
国产欧美一区二区在线| 欧美大白屁股肥臀xxxxxx| 亚洲成av人片在线| 亚洲国产欧美在线| 色婷婷亚洲精品| 337p日本欧洲亚洲大胆色噜噜| 日韩av午夜在线观看| 99久久国产综合精品女不卡| 成人动漫一区二区在线| 国产精品少妇自拍| 午夜精品福利一区二区三区蜜桃| 国产精品18久久久久久vr| 欧美成人三级在线| 欧美视频在线不卡| 亚洲国产精品一区二区久久恐怖片| 日韩1区2区3区| 日韩欧美在线观看一区二区三区| 一区二区三区高清| 在线一区二区三区四区| 国产欧美久久久精品影院| 成人性视频免费网站| 欧美日韩在线三区| 青青草91视频| 日本一区二区三级电影在线观看| 91免费在线看| 日产国产高清一区二区三区| 亚洲一卡二卡三卡四卡 | 午夜精品一区在线观看| 久久精品久久99精品久久| 国产偷国产偷亚洲高清人白洁| 欧美一区二区三区在线视频| 色婷婷一区二区| 中文字幕亚洲成人| 亚洲欧美日韩精品久久久久| 国产精品成人免费精品自在线观看| 精品少妇一区二区| 精品免费国产二区三区| 欧美大肚乱孕交hd孕妇| 中文字幕欧美日韩一区| 亚洲一线二线三线视频| 蜜桃一区二区三区四区| 成人av动漫网站| 欧美人与禽zozo性伦| 日韩欧美中文一区| 国产精品久久久久精k8| 欧洲一区在线观看| 精品国产乱码久久久久久免费| 精品在线播放免费| 欧美高清一级片在线| 亚洲欧美视频一区| 美女视频黄 久久| 欧美va在线播放| 一区二区三区日韩| 日韩免费视频线观看| aaa国产一区| 欧美性猛交xxxx乱大交退制版 | 国产精品亚洲成人| 91免费在线看| 日韩美女在线视频| 国产精品国产三级国产普通话蜜臀| 亚洲欧美偷拍卡通变态| 国产福利一区二区三区视频| 国产精品久久久久久亚洲伦| 亚洲精品ww久久久久久p站| 91精品国产一区二区人妖| 欧美性做爰猛烈叫床潮| 国产专区欧美精品| 欧美视频一区在线| 精品久久久久久久久久久久包黑料| www国产亚洲精品久久麻豆| 欧美精品一区二区在线观看| 亚洲图片欧美色图| 欧美美女视频在线观看| 国内外成人在线| 91精品国产高清一区二区三区蜜臀| 91蝌蚪porny九色| 91在线porny国产在线看| 欧美日韩1234| 亚洲另类一区二区| 91香蕉视频mp4| 亚洲欧美偷拍三级| 色婷婷久久久亚洲一区二区三区 | 精品国产乱码91久久久久久网站| 久久99国内精品| 中文字幕不卡在线播放| 在线精品视频小说1| 亚洲视频在线观看一区| 国产成人在线视频免费播放| 99国产精品视频免费观看| 91精品啪在线观看国产60岁| 国产欧美久久久精品影院| 国产一区二区在线电影| 亚洲三级在线观看| 久久久久久久国产精品影院| 丁香婷婷深情五月亚洲| 亚洲不卡av一区二区三区| 国产精品久久久久久久久动漫| 91精品一区二区三区久久久久久 | 精品视频免费看| 欧美一区二区视频观看视频| 毛片一区二区三区| 亚洲午夜久久久久久久久电影网 | 337p日本欧洲亚洲大胆精品| 欧美电影免费观看高清完整版在线观看 | 蜜桃在线一区二区三区| 91成人免费电影| 性做久久久久久免费观看欧美| 午夜私人影院久久久久| 国产精品一级在线| 欧美tk—视频vk| 国产乱码精品1区2区3区| 一区二区三区在线观看网站| 免费成人av在线| 欧美在线观看视频一区二区| 日韩欧美一区二区不卡| 亚洲一区二区五区| 亚洲精品乱码久久久久| 精品久久一二三区| 日韩欧美精品在线| 国产清纯白嫩初高生在线观看91 | 91网址在线看| 久久综合网色—综合色88| 青青草精品视频| 欧美精选在线播放| 2021国产精品久久精品| 欧美日韩不卡视频| 欧美日韩国产小视频在线观看| 欧美色区777第一页| av不卡一区二区三区| 欧美色欧美亚洲另类二区| 亚洲午夜一二三区视频| 欧美激情一区二区在线| 欧美一区二区观看视频| 91精品久久久久久久99蜜桃| xnxx国产精品| 一区二区激情视频| 另类人妖一区二区av| 亚洲电影中文字幕在线观看| 国产东北露脸精品视频| 国产乱理伦片在线观看夜一区| 26uuu欧美| 免费一区二区视频| 国产亚洲成年网址在线观看| 麻豆成人久久精品二区三区红| 懂色av中文一区二区三区| 欧美日韩小视频| 欧美激情一区在线观看| 日本一区二区视频在线| 蜜桃视频在线观看一区二区| 精品国产网站在线观看| 韩国精品在线观看| 国产精品毛片高清在线完整版| 国产精品免费久久| 99国产精品久久| 国产亚洲自拍一区| 久久香蕉国产线看观看99| 色综合天天性综合| 久久er99热精品一区二区| 免费av网站大全久久| 精品久久久久久久久久久院品网| 亚洲一区二区在线免费看| 欧美剧情电影在线观看完整版免费励志电影| 亚洲不卡av一区二区三区| 国产日韩欧美亚洲| 欧美精品三级日韩久久| 成人深夜在线观看| 色美美综合视频| 欧美亚一区二区| 91精品国产综合久久精品麻豆| 日韩二区在线观看| 国产精品女人毛片| 欧美性色黄大片| bt欧美亚洲午夜电影天堂| 国产精品主播直播| 国产麻豆成人精品| 久久久久久久久久美女| 久久久久久综合| 中文字幕av资源一区| 欧美激情一区在线| 日产国产高清一区二区三区| 裸体健美xxxx欧美裸体表演| 国产婷婷一区二区| 国产精品久久久久久久久久久免费看| 精品剧情v国产在线观看在线| 日韩午夜三级在线| 国产精品乱子久久久久| 免费一区二区视频| 美国av一区二区| 91免费小视频| 久久精品欧美一区二区三区麻豆| 亚洲日本电影在线| wwww国产精品欧美| 久久99国产精品久久99| 国产在线播放一区| 日韩一级免费观看| www.亚洲在线| 欧美日韩国产高清一区二区| 久久爱www久久做| 亚洲视频一区二区在线| 日韩成人午夜电影|