1. 程式人生 > >從REST引申到對http協議中 get、post、put、delete理解

從REST引申到對http協議中 get、post、put、delete理解

最近在寫公司程式碼時候,因為是Restful風格的微服務架構,介面上我們要寫上對應的URL和請求型別,原來只是簡單的理解為get查詢,delete刪除,post建立,put用來查詢。但昨天寫方法的時候組長在一個方法用post和put猶豫了下。我感覺肯定有問題。而且自己對Rest原則好像也是似懂非懂的。所以網上找了下資料,整理了下。

1.什麼是Rest

    REST這個詞,是Roy Thomas Fielding在他2000年的博士論文中提出的,裡面有下面一段:

    "本文研究電腦科學兩大前沿----軟體和網路----的交叉點。長期以來,軟體研究主要關注軟體設計的分類、設計方法的演化,很少客觀地評估不同的設計選擇對系統行為的影響。而相反地,網路研究主要關注系統之間通訊行為的細節、如何改進特定通訊機制的表現,常常忽視了一個事實,那就是改變應用程式的互動風格比改變互動協議,對整體表現有更大的影響

。我這篇文章的寫作目的,就是想在符合架構原理的前提下,理解和評估以網路為基礎的應用軟體的架構設計,得到一個功能強、效能好、適宜通訊的架構。"
    (This dissertation explores a junction on the frontiers of two research disciplines in computer science: software and networking. Software research has long been concerned with the categorization of software designs and the development of design methodologies, but has rarely been able to objectively evaluate the impact of various design choices on system behavior. Networking research, in contrast, is focused on the details of generic communication behavior between systems and improving the performance of particular communication techniques, often ignoring the fact that changing the interaction style of an application can have more impact on performance than the communication protocols used for that interaction. My work is motivated by the desire to understand and evaluate the architectural design of network-based application software through principled use of architectural constraints, thereby obtaining the functional, performance, and social properties desired of an architecture. )

   我的理解用在上面那段話標記出來了,Rest是論文裡提出的一種規範,它用於規範的是在原有網路傳輸協議(如http協議)不變的前提之上提出了一種應用之間互動風格。

2.Rest的互動風格是啥樣的?

首先,在瞭解網路互動風格的時候,我們得知道我們互動的是啥...

    互動的是 -- 資源! 啥是資源?

    所謂"資源",就是網路上的一個實體,或者說是網路上的一個具體資訊。它可以是一段文字、一張圖片、一首歌曲、一種服務,一個html、一個jsp總之就是一個具體的實在。你可以用一個 URI(統一資源定位符,URL和URI的關係可以看下這個連結:http://blog.csdn.net/Inuyasha1121/article/details/49799915)指向它,每種資源對應一個特定的URI。要獲取這個資源,訪問它的URI就可以,因此URI就成了每一個資源的地址或獨一無二的識別符。

    這種互動風格有什麼要求:

        1.每個資源都應該有一個唯一的標識    URI  
        2.使用標準的方法來更改資源的狀態    像HTTP下的
        3.Request和Response的自描述
        4.資源多重表述
        5.無狀態的服務

        幾個標準的具體含義就直接放個連結了,有時間可以深入瞭解下:http://blog.csdn.net/zitong_ccnu/article/details/47779547

        如果一個架構符合REST互動風格要求,就稱它為RESTful架構。

        REST互動風格要求下HTTP協議的操作風格是這樣的:

        客戶端用到的手段,只能是HTTP協議。具體來說,就是HTTP協議裡面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操作:GET用來獲取資源,POST用來新建資源(也可以用於更新資源),PUT用來更新資源,DELETE用來刪除資源。

              HTTP協議下RestFul框架的互動格式就像這樣:   
              POST /uri 建立
              DELETE /uri/xxx 刪除
              PUT /uri/xxx 更新或建立
              GET /uri/xxx 檢視

             post和put都可以用來建立,這個就得弄清楚建立的區別啦。網上查了下,基本上都是說冪等性的,我就不再說了直接說下自己理解吧,post的建立是不安全的,我們每次建立都會創建出一個資源,而put是安全的他建立的物件包含唯一的資訊,如果建立了,就不會在建立。打個比方建立一個人物件,用post發{男人}{女人}{男人}包含id,他會創建出{1:男人}{2:女人}{3:男人},而在使用put時候得發{1:男人},他會建立一個{1:男人},再發{1:女人}他就會修改原有的資訊最後留下的是{1:女人},這裡不是說我們用了post或者put就得這麼幹。而是結合我們方法產生的具體效果來選擇用post或者get。

3.誤區

    最常見的一種設計錯誤,就是URI包含動詞。因為"資源"表示一種實體,所以應該是名詞,URI不應該有動詞,動詞應該放在HTTP協議中。
舉例來說,某個URI是/posts/show/1,其中show是動詞,這個URI就設計錯了,正確的寫法應該是/posts/1,然後用GET方法表示show。
如果某些動作是HTTP動詞表示不了的,你就應該把動作做成一種資源。比如網上匯款,從賬戶1向賬戶2匯款500元,錯誤的URI是:
  POST /accounts/1/transfer/500/to/2
正確的寫法是把動詞transfer改成名詞transaction,資源不能是動詞,但是可以是一種服務:
  POST /transaction HTTP/1.1
  Host: 127.0.0.1
  from=1&to=2&amount=500.00
另一個設計誤區,就是在URI中加入版本號:
  http://www.example.com/app/1.0/foo
  http://www.example.com/app/1.1/foo
  http://www.example.com/app/2.0/foo
因為不同的版本,可以理解成同一種資源的不同表現形式,所以應該採用同一個URI。版本號可以在HTTP請求頭資訊的Accept欄位中進行區分(參見Versioning REST Services):
  Accept: vnd.example-com.foo+json; version=1.0
  Accept: vnd.example-com.foo+json; version=1.1
  Accept: vnd.example-com.foo+json; version=2.0

4.Http中的GET、POST、PUT、DELETE請求

    我們常常會碰到一個問題,問get的post的區別,我想大部分學網頁開發的最開始都是解除這兩個請求。答案大部分會想到下面中的:

    GET在瀏覽器回退時是無害的,而POST會再次提交請求。
    GET產生的URL地址可以被Bookmark,而POST不可以。
    GET請求會被瀏覽器主動cache,而POST不會,除非手動設定。
    GET請求只能進行url編碼,而POST支援多種編碼方式。
    GET請求引數會被完整保留在瀏覽器歷史記錄裡,而POST中的引數不會被保留。
    GET請求在URL中傳送的引數是有長度限制的,而POST麼有。
    對引數的資料型別,GET只接受ASCII字元,而POST沒有限制。
    GET比POST更不安全,因為引數直接暴露在URL上,所以不能用來傳遞敏感資訊。
    GET引數通過URL傳遞,POST放在Request body中。

     但是這些差別是http規定的嗎?我們看看原理:

     http協議是做用於應用層的一種協議,計算機網路裡面學了應用層 下面有傳輸層,而傳輸層就有大名鼎鼎的tcp 和udp傳輸協議。而socket是作業系統為一套我們操作傳輸層的介面,http就是基於此之上建立的。所以我們的get、post、put、delete可以理解為一次tcp的連線併發送一次請求,可能有疑惑,每次發請求都伴隨一次tcp的連線與釋放(有三次握手啥的,大學的忘了好多。。。)嗎?那效率不是很慢?記得以前在哪看到,好像新的http協議,我們建立一次tcp連線可以傳輸多次請求,比方說我們建立一次連線請求了一個html,html所需的css請求也在這次連結完成。 具體的我也沒有深入瞭解。

     而連線多了以後怎麼管理呢?http協議就提出了分類,也就是get、post、put、delete。 這是一種規範,就像你可以在get的協議體裡傳參,也可以在post url上傳參,但是這是不優雅的哈哈。那上面說的引數長度的限制是怎麼回事呢?這其實是瀏覽器所限制的,與http協議中並沒有限制他。 而http不推薦的get請求體傳參,有的瀏覽器也會幫我們遮蔽掉,有的不會。

4.談談get、post、put、delete和Rest的關

    上面我們說Rest又一個要求是得有一套標準的方法操作網路上的資源,而這四種剛好滿足他的要求。

5. 最後說下自己的理解吧,早期網際網路不發達的是時候,網上請求僅使用get/post 一個引數在外,一個引數在內。就已經滿足了要求網際網路之間訪問的要求。而現在隨著網際網路的發展,服務與服務之間互動非常平繁, 專案內部現在越來越流行微服務架構啥的,得相互呼叫。外部比如我們登陸很多網站可以用qq登陸。得呼叫騰訊的服務。 之前的get post已經很難使我們呼叫變得清晰明瞭。所以引入了Rest,他規範了我們遠端呼叫的互動行為。

上面都是自己結合別人的帖子加上自己的理解總結的,錯我別怪我誤導。。那是我也理解錯了,還望多多指點哈哈