Restful風格API中用put還是post做新增操作有什么區別?


Restful風格API中用put還是post做新增操作有什么區別?

                                    <div class="content" id="articleContent">
                                                <div class="ad-wrap">
                                                    <p style="margin:0 0 10px 0;"><a data-traceid="blog_detail_above_text_link_1" data-tracepid="blog_detail_above_text_link" style="color:#A00;font-weight:bold;" href="https://my.oschina.net/u/2663968/blog/3109540" target="_blank">頭條面試歸來,有些話想和Java開發者說!&gt;&gt;&gt; </a>  <img src="https://www.oschina.net/img/hot3.png" align="absmiddle" style="max-height: 32px; max-width: 32px;"></p>
                                    </div>
                                            <p><span style="color:#2E2E2E">這個是華為面試官問我的問題,回來我找了很多資料,想驗證這個問題。在回答問題之前,還需要搜集一些基礎知識。</span></p> 

HTTP協議詳解

HTTP是HyperText Transfer Protocol(超文本傳輸協議)的縮寫。它的發展是萬維網協會(WorldWide Web Consortium)和Internet工作小組IETF(Internet Engineering Task Force)合作的結果,(他們)最終發布了一系列的RFC,RFC 1945定義了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定義了今天普遍使用的一個版本——HTTP 1.1。

HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先於圖形)等。

HTTP協議通常承載於TCP協議之上,有時也承載於TLS或SSL協議層之上,這個時候,就成了我們常說的HTTPS。如下圖所示:

            

 

默認HTTP的端口號為80,HTTPS的端口號為443。

HTTP協議永遠都是客戶端發起請求,服務器回送響應。見下圖:
    

這樣就限制了使用HTTP協議,無法實現在客戶端沒有發起請求的時候,服務器將消息推送給客戶端。

HTTP協議是一個無狀態的協議,同一個客戶端的這次請求和上次請求是沒有對應關系。

一次HTTP操作稱為一個事務,其工作過程可分為四步:

1)首先客戶機與服務器需要建立連接。只要單擊某個超級鏈接,HTTP的工作開始。

2)建立連接后,客戶機發送一個請求給服務器,請求方式的格式為:統一資源標識符(URL)、協議版本號,后邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。

3)服務器接到請求后,給予相應的響應信息,其格式為一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,后邊是MIME信息包括服務器信息、實體信息和可能的內容。

4)客戶端接收服務器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然后客戶機與服務器斷開連接。

如果在以上過程中的某一步出現錯誤,那么產生錯誤的信息將返回到客戶端,有顯示屏輸出。對於用戶來說,這些過程是由HTTP自己完成的,用戶只要用鼠標點擊,等待信息顯示就可以了。

 HTTP協議詳解之請求篇

  http請求由三部分組成,分別是:請求行、消息報頭、請求正文

請求行以一個方法符號開頭,以空格分開,后面跟着請求的URI和協議的版本,格式如下:Method Request-URIHTTP-Version CRLF  
其中 Method表示請求方法;Request-URI是一個統一資源標識符;HTTP-Version表示請求的HTTP協議版本;CRLF表示回車和換行(除了作為結尾的CRLF外,不允許出現單獨的CR或LF字符)。

請求方法(所有方法全為大寫)有多種,各個方法的解釋如下:
GET     請求獲取Request-URI所標識的資源
POST    在Request-URI所標識的資源后附加新的數據
HEAD    請求獲取由Request-URI所標識的資源的響應消息報頭
PUT     請求服務器存儲一個資源,並用Request-URI作為其標識
DELETE  請求服務器刪除Request-URI所標識的資源
TRACE   請求服務器回送收到的請求信息,主要用於測試或診斷
CONNECT 保留將來使用
OPTIONS 請求查詢服務器的性能,或者查詢與資源相關的選項和需求
應用舉例:
GET方法:在瀏覽器的地址欄中輸入網址的方式訪問網頁時,瀏覽器采用GET方法向服務器獲取資源,eg:GET /form.html HTTP/1.1 (CRLF)

POST方法要求被請求服務器接受附在請求后面的數據,常用於提交表單。

HEAD方法與GET方法幾乎是一樣的,對於HEAD請求的回應部分來說,它的HTTP頭部中包含的信息與通過GET請求所得到的信息是相同的。利用這個方法,不必傳輸整個資源內容,就可以得到Request-URI所標識的資源的信息。該方法常用於測試超鏈接的有效性,是否可以訪問,以及最近是否更新。
 

 HTTP協議詳解之響應篇

在接收和解釋請求消息后,服務器返回一個HTTP響應消息。

HTTP響應也是由三個部分組成,分別是:狀態行、消息報頭、響應正文
1、狀態行格式如下:

HTTP-VersionStatus-Code Reason-Phrase CRLF
其中,HTTP-Version表示服務器HTTP協議的版本;Status-Code表示服務器發回的響應狀態代碼;Reason-Phrase表示狀態代碼的文本描述。
狀態代碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值:
1xx:指示信息--表示請求已接收,繼續處理
2xx:成功--表示請求已被成功接收、理解、接受
3xx:重定向--要完成請求必須進行更進一步的操作
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現
5xx:服務器端錯誤--服務器未能實現合法的請求
2、常見狀態代碼、狀態描述、說明:

請求收到,繼續處理
100——客戶必須繼續發出請求
101——客戶要求服務器根據請求轉換HTTP協議版本
操作成功收到,分析、接受
200——交易成功
201——提示知道新文件的URL
202——接受和處理、但處理未完成
203——返回信息不確定或不完整
204——請求收到,但返回信息為空
205——服務器完成了請求,用戶代理必須復位當前已經瀏覽過的文件
206——服務器已經完成了部分用戶的GET請求
完成此請求必須進一步處理
300——請求的資源可在多處得到
301——刪除請求數據
302——在其他地址發現了請求數據
303——建議客戶訪問其他URL或訪問方式
304——客戶端已經執行了GET,但文件未變化
305——請求的資源必須從服務器指定的地址得到
306——前一版本HTTP中使用的代碼,現行版本中不再使用
307——申明請求的資源臨時性刪除
請求包含一個錯誤語法或不能完成
400——錯誤請求,如語法錯誤
401——未授權
HTTP 401.1 - 未授權:登錄失敗
   HTTP 401.2 - 未授權:服務器配置問題導致登錄失敗
   HTTP 401.3 - ACL 禁止訪問資源
   HTTP 401.4 - 未授權:授權被篩選器拒絕
HTTP 401.5 - 未授權:ISAPI 或 CGI 授權失敗
402——保留有效ChargeTo頭響應
403——禁止訪問
HTTP 403.1 禁止訪問:禁止可執行訪問
   HTTP 403.2 - 禁止訪問:禁止讀訪問
   HTTP 403.3 - 禁止訪問:禁止寫訪問
   HTTP 403.4 - 禁止訪問:要求 SSL
   HTTP 403.5 - 禁止訪問:要求 SSL128
   HTTP 403.6 - 禁止訪問:IP 地址被拒絕
   HTTP 403.7 - 禁止訪問:要求客戶證書
   HTTP 403.8 - 禁止訪問:禁止站點訪問
   HTTP 403.9 - 禁止訪問:連接的用戶過多
   HTTP 403.10 - 禁止訪問:配置無效
   HTTP 403.11 - 禁止訪問:密碼更改
   HTTP 403.12 - 禁止訪問:映射器拒絕訪問
   HTTP 403.13 - 禁止訪問:客戶證書已被吊銷
   HTTP 403.15 - 禁止訪問:客戶訪問許可過多
   HTTP 403.16 - 禁止訪問:客戶證書不可信或者無效
HTTP 403.17 - 禁止訪問:客戶證書已經到期或者尚未生效
404——沒有發現文件、查詢或URl
405——用戶在Request-Line字段定義的方法不允許
406——根據用戶發送的Accept拖,請求資源不可訪問
407——類似401,用戶必須首先在代理服務器上得到授權
408——客戶端沒有在用戶指定的餓時間內完成請求
409——對當前資源狀態,請求不能完成
410——服務器上不再有此資源且無進一步的參考地址
411——服務器拒絕用戶定義的Content-Length屬性請求
412——一個或多個請求頭字段在當前請求中錯誤
413——請求的資源大於服務器允許的大小
414——請求的資源URL長於服務器允許的長度
415——請求資源不支持請求項目格式
416——請求中包含Range請求頭字段,在當前請求資源范圍內沒有range指示值,請求也不包含If-Range請求頭字段
417——服務器不滿足請求Expect頭字段指定的期望值,如果是代理服務器,可能是下一級服務器不能滿足請求長。
服務器執行一個完全有效請求失敗
  
HTTP 500 - 內部服務器錯誤
   HTTP 500.100 - 內部服務器錯誤 -ASP 錯誤
   HTTP 500-11 服務器關閉
   HTTP 500-12 應用程序重新啟動
   HTTP 500-13 - 服務器太忙
   HTTP 500-14 - 應用程序無效
   HTTP 500-15 - 不允許請求 global.asa
   Error 501 - 未實現
        HTTP 502 - 網關錯誤
   HTTP 500.100 - 內部服務器錯誤 -ASP 錯誤
   HTTP 500-11 服務器關閉
   HTTP 500-12 應用程序重新啟動
   HTTP 500-13 - 服務器太忙
   HTTP 500-14 - 應用程序無效
   HTTP 500-15 - 不允許請求 global.asa
   Error 501 - 未實現
        HTTP 502 - 網關錯誤

4 API設計的基本要求

  一個被普遍承認和遵守:RESTful設計原則。它被Roy Felding提出(在他的”基於網絡的軟件架構“論文中第五章)。而REST的核心原則是將你的API拆分為邏輯上的資源。這些資源通過http被操作(GET ,POST,PUT,DELETE)。
    顯然從API用戶的角度來看,”資源“應該是個名詞。即使你的內部數據模型和資源已經有了很好的對應,API設計的時候你仍然不需要把它們一對一的都暴露出來。這里的關鍵是隱藏內部資源,暴露必需的外部資源。
    一旦定義好了要暴露的資源,你可以定義資源上允許的操作,以及這些操作和你的API的對應關系:
 

·       GET /tickets # 獲取ticket列表

·       GET /tickets/12 # 查看某個具體的ticket

·       POST /tickets # 新建一個ticket

·       PUT /tickets/12 # 更新ticket 12.

·       DELETE /tickets/12 #刪除ticekt 12

    可以看出使用REST的好處在於可以充分利用http的強大實現對資源的CURD功能。而這里你只需要一個endpoint:/tickets,再沒有其他什么命名規則和url規則了,cool!
    但是有的endpoint,需要使用復數使得你的URL更加規整。這讓API使用者更加容易理解,對開發者來說也更容易實現。
如何處理關聯?關於如何處理資源之間的管理REST原則也有相關的描述:

·       GET /tickets/12/messages- Retrieves list of messages forticket #12

·       GET /tickets/12/messages/5- Retrieves message #5 forticket #12

·       POST /tickets/12/messages- Creates a new message inticket #12

·       PUT /tickets/12/messages/5- Updates message #5 for ticket#12

·       PATCH /tickets/12/messages/5- Partially updates message#5 for ticket #12

·       DELETE /tickets/12/messages/5- Deletes message #5 forticket #12

    其中,如果這種關聯和資源獨立,那么我們可以在資源的輸出表示中保存相應資源的endpoint。然后API的使用者就可以通過點擊鏈接找到相關的資源。如果關聯和資源聯系緊密。資源的輸出表示就應該直接保存相應資源信息。(例如這里如果message資源是獨立存在的,那么上面 GET/tickets/12/messages就會返回相應message的鏈接;相反的如果message不獨立存在,他和ticket依附存在,則上面的API調用返回直接返回message信息)

5 get和post區別

    常用的請求方式是GET和POST.

GET方式:是以實體的方式得到由請求URI所指定資源的信息,如果請求URI只是一個數據產生過程,那么最終要在響應實體中返回的是處理過程的結果所指向的資源,而不是處理過程的描述。

POST方式:用來向目的服務器發出請求,要求它接受被附在請求后的實體,並把它當作請求隊列中請求URI所指定資源的附加新子項,Post被設計成用統一的方法實現下列功能:

1)對現有資源的解釋;

2)向電子公告欄、新聞組、郵件列表或類似討論組發信息;

3)提交數據塊;

4)通過附加操作來擴展數據庫 。

從上面描述可以看出,Get是向服務器發索取數據的一種請求;而Post是向服務器提交數據的一種請求,要提交的數據位於信息頭后面的實體中。

GET與POST方法有以下區別:

1)   在客戶端,Get方式在通過URL提交數據,數據在URL中可以看到;POST方式,數據放置在HTMLHEADER內提交。

2)  GET方式提交的數據最多只能有1024字節,而POST則沒有此限制。

3)   安全性問題。正如在(1)中提到,使用 Get 的時候,參數會顯示在地址欄上,而 Post 不會。所以,如果這些數據是中文數據而且是非敏感數據,那么使用 get;如果用戶輸入的數據不是中文字符而且包含敏感數據,那么還是使用 post為好。

4)   安全的和冪等的。所謂安全的意味着該操作用於獲取信息而非修改信息。冪等的意味着對同一 URL 的多個請求應該返回同樣的結果。完整的定義並不像看起來那樣嚴格。換句話說,GET 請求一般不應產生副作用。從根本上講,其目標是當用戶打開一個鏈接時,她可以確信從自身的角度來看沒有改變資源。比如,新聞站點的頭版不斷更新。雖然第二次請求會返回不同的一批新聞,該操作仍然被認為是安全的和冪等的,因為它總是返回當前的新聞。反之亦然。POST 請求就不那么輕松了。POST 表示可能改變服務器上的資源的請求。仍然以新聞站點為例,讀者對文章的注解應該通過 POST 請求實現,因為在注解提交之后站點已經不同了(比方說文章下面出現一條注解)。

6 put和post區別

  有的觀點認為,應該用POST來創建一個資源,用PUT來更新一個資源;有的觀點認為,應該用PUT來創建一個資源,用POST來更新一個資源;還有的觀點認為可以用PUT和POST中任何一個來做創建或者更新一個資源。這些觀點都只看到了風格,爭論起來也只是爭論哪種風格更好,其實,用PUT還是POST,不是看這是創建還是更新資源的動作,這不是風格的問題,而是語義的問題。
  舉一個簡單的例子,假如有一個博客系統提供一個Web API,模式是這樣http://superblogging/blogs/{blog-name},很簡單,將{blog-name}
替換為我們的blog名字,往這個URI發送一個HTTP PUT或者POST請求,HTTP的body部分就是博文,這是一個很簡單的REST API例子。我們應該用
PUT方法還是POST方法?取決於這個REST服務的行為是否是idempotent的,假如我們發送兩個http://superblogging/blogs/post/Sample請求,服
務器端是什么樣的行為?如果產生了兩個博客帖子,那就說明這個服務不是idempotent的,因為多次使用產生了副作用了嘛;如果后一個請求把第一個
請求覆蓋掉了,那這個服務就是idempotent的。前一種情況,應該使用POST方法,后一種情況,應該使用PUT方法。

 

 

參考資料:

http://www.ruanyifeng.com/blog/2011/09/restful

http://kb.cnblogs.com/page/512047/

                                    </div>
                                        </div>
                <div class="ui hidden divider"></div>
                <p style="text-align:center;">
                                                本文轉載自:http://blog.csdn.net/chlu113/article/details/51853331
                                        </p>
            </div>
posted @ 2019-09-27 16:09  星朝  閱讀( 505)  評論( 0編輯  收藏


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM