RESTful GET,如果存在大量參數,是否有必要變通一下?

來源:互聯網
上載者:User
關鍵字 RESTful GET description status create
比如設計一個GET介面,用來擷取滿足條件的商品
GET shop/1/goods?
參數可能是五花八門的,name,create_time,description, status, owner...

通常這種情況,如果不考慮RESTful,就會設計成POST。

但是現在RESTful風格要求做成GET,如何處理會比較合適?

回複內容:

先說結論,可以,使用POST來處理參數比較長的search請求並沒有違反REST。

再說說@張立理 同學的答案裡可以改進的地方。在張同學的理論主義玩法裡:
有這樣的URL:
/goods/ 商品集合
變通不是必要的。如果是因為URI可能超長,導致了某個組件不支援,那麼換一個組件就好了。

根據 Fielding Dissertation: CHAPTER 6: Experience and Evaluation 6.3.2.5 Size Limits 裡提到的:
There is no limit in the HTTP protocol on the length of URI
儘管
Although older Web clients have a well-known problem with URI that consist of more than 255 characters
解決方案是:
applications within a controlled context (such as an intranet) can avoid those limits by replacing the older components
首先承認超過GET的URL總長度的情況確實可能存在的,一個比較典型的情境就是多選id,鬼知道一個變態能選出多少個來

當然一個合理的應用不應該讓這種情況出現,畢竟用手勾選到能超過URL的長度限制應該是會抽筋的,我們親愛的產品組應該為使用者著想
至於“全選”和“全選後取消幾個”這種情境,其一我很懷疑後者的使用者情境是否真的存在,其二可以使用全選和反選標記來給予實現,也並不是什麼麻煩事兒

繼續說真的超過了URL長度限制怎麼辦,第一反應自然是拿POST來玩,但是使用POST除去教條式的語義性和REST規範之外,一個很嚴重的影響是 無法使用HTTP緩衝
當然這個也不是什麼大問題,畢竟 99.99%的應用是不會精心設計HTTP緩衝的(是的這句話是在噴包括自己在內的很多工程師),所以搜尋這種情境從一開始就幾乎是沒有HTTP緩衝支援

那如果我還是想要緩衝,還是想要遵守REST規範使用GET怎麼辦呢?這裡有一個理論主義的玩法
假設我們對商品進行檢索,有這樣的URL:

/goods/ 商品集合
get也可以帶body樓主的問題是一個很典型的問題,經常有人問我。我的回答一律是:別折騰了,你們根本就做不了RESTful。

絕大部分人都理解RESTful是一種介面的設計形式,然後發現很多時候某些需求根本沒法做成RESTful形式的,但就我看來RESTful是從底層架構就應該考慮的問題,或者說是一種架構設計思想,而不僅僅只針對於介面。

比如題主的這個情況,如果要讓我來做,我會設計兩個介面
POST /shop/1/query 建立一個商品的查詢,返回id
GET /shop/1/query/{id} 擷取某個查詢的結果

為什麼要這麼設計?
1.RESTful中,URI代表資源,html/圖片這類檔案是資源,query這類服務也是資源
2.RESTful中,POST用來建立或者更新,GET用來擷取資源

但是很顯然,這肯定不滿足題主的需求,要這樣做現有的架構肯定滿足不了,所以我勸題主別折騰什麼RESTful了,怎麼好做怎麼來---更新 20160213 ---

突然發現貌似 Polyfill 的方案好像和 @立青 童鞋的想法類似。。

---更新 20160213 ---

正如 @張立理@劉尚奇 所說,確實查詢條件過長的情況有可能存在,但是傾向於認為其設計的 API 過於複雜(對於每一種 Entity 的介面,都要另外設計一個 Query 的介面),並且導致了有條件查詢和無條件查詢介面的不一致性,以及使用了一個沒有確切 Representation 的中間類型。所以在此重新給出一個簡潔一致的通用介面。

1. 無條件查詢:


直接 GET。
GET /goods HTTP/1.1
GET /xxx?type=[1|2|3|4|5|6|7|8] 百試不爽,但是!別打我!前端用的也挺happy的⋯⋯要麼是get帶query string,要麼是post帶body。get帶body不符合http規範,這麼做有後患。

權衡因素:
  • query string的長度限制,因用戶端瀏覽器(Firefox, Chrome, IE)和伺服器(Apache, IIS)而異。query string除了普通的索引值對,還可以包含集合參數,後者是有可能超出長度限制的,要小心
  • get+query string對cache更友好
  • get+query string可加入瀏覽器收藏夾
  • get+query string對搜尋引擎更友好
對於複雜search做成post,不見得就違反了Restful。你可以理解為,每次search的結果是一個新建立的臨時集合。restful本來就是拿來裝的,沒必要那麼較真首先, REST 是一種設計風格而不是標準,如果一個架構符合 REST 原則,我們就稱它為 RESTful 架構。

其關鍵就在於如何抽象資源,抽象得越好,介面設計也就越加符合 REST 風格,即能夠享受到更多 HTTP 所帶來的「好處」,要知道 Roy Fielding 是在完成 HTTP 1.1 設計之後才回到大學讀博,在博士論文中總結出了 REST

然而,如同所有程式世界的矛盾一樣,現實中的抽象問題永遠無法得到完美的映射。

=====================進入正題=====================

搜尋能不能抽象成一個資源,這取決於你怎麼看待和使用這個介面。通常來說一個資源會有 CURD 幾種介面,如果硬要套用 REST的理念 對應到「搜尋」這個資源其實可以這麼理解:

拆分成 create(POST)和 read(GET)這兩種介面,create 通過 POST 方法把關鍵字傳給伺服器建立一個資源,然後再通過 GET 方法顯示最後的搜尋結果。

而與此同時還有一個好處就是記錄使用者的搜尋曆史,一個使用者資源連結著多個 Search 資源,每個資源只有自己的 GET 方法,只不過是我們沒有在伺服器提供其他方法的映射。
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.