成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

7點關于RESTful規(guī)范的API接口設計的想法

Jason / 3101人閱讀

摘要:返回值結構在完成了上面的部署之后,接下來我們來看看返回結果應該怎么樣來確定。因為返回值中,我們常常要對數據進行區(qū)分分組,或者按照從屬關系打包,所以,我們再返回時,最好有包裹的思想,把數據存放在不同的包裹中進行返回。

在項目中,需要為APP撰寫API。剛開始接觸的時候,并沒有考慮太多,就想提供URL,APP端通過該URL進行查詢、創(chuàng)建、更新等操作即可。但再對相關規(guī)范進行了解后,才發(fā)現,API的設計并沒有那么簡單,遠遠不是URL的問題,而是一個通信協議的整體架構。因此,我寫這篇文章,用來記錄自己的一些心得,并不斷完善。并提供關于RESTful API的一些參考文獻。

1. 使用SSL(https)來提供URL

首先,使用https可以在數據包被抓取時多一層加密。我們現在的APP使用環(huán)境大部分都是在路由器WIFI環(huán)境下,一旦路由器被入侵,那么黑客可以非常容易的抓取到用戶通過路由器傳輸的數據,如果使用http未經加密,那么黑客可以很輕松的獲取用戶的信息,甚至是賬戶信息。

其次,即使使用https,也要在API數據傳輸設計時,正確的采用加密。例如直接將token信息放在URL中的做法,即使你使用了https,黑客抓不到你具體傳輸的數據,但是可以抓到你請求的URL啊!(查了資料了,https用GET方式請求,也僅能抓到域名字符部分,不能抓到請求的數據,但是URL可以在瀏覽器或特殊客戶端工具中直接看到。多謝下面的朋友指正錯誤)因此,使用https進行請求時,要采用POST、PUT或者HEAD的方式傳輸必要的數據。

2. 使用GET、POST、PUT、DELETE這幾種請求模式

請求模式也可以說是動作、數據傳輸方式,通常我們在web中的form有GET、POST兩種,而在HTTP中,存在下發(fā)這幾種。

GET (選擇):從服務器上獲取一個具體的資源或者一個資源列表。
POST (創(chuàng)建): 在服務器上創(chuàng)建一個新的資源。
PUT(更新):以整體的方式更新服務器上的一個資源。
PATCH (更新):只更新服務器上一個資源的一個屬性。
DELETE(刪除):刪除服務器上的一個資源。
HEAD : 獲取一個資源的元數據,如數據的哈希值或最后的更新時間。
OPTIONS:獲取客戶端能對資源做什么操作的信息。

3. 在URI中體現資源,而非動作

閱讀RESTful架構的參考文獻之后,你會了解什么是資源的概念,以及REST的確切含義。再構建API的URL的時候,URI中應該僅包含資源(對象),而不要加入動作。比如 /user/1/update ,其中update就是一個動作,雖然我們希望通過這個URI來實現用戶ID為1的用戶進行信息更新,但是按照RESTful的規(guī)范,作為動作,應該用上面的PUT來表示,所以請求更新用戶信息,應該使用 PUT /user/1 來表示更新用戶ID為1的用戶信息。

如果去對應上面的請求模式,GET表示顯示、列出、展示,POST表示提交、創(chuàng)建,PUT表示更新,DELETE表示刪除。


上面這段代碼中$url僅僅是提供到了user,而并沒有提供add,服務端通過識別POST請求來確定,這是一個創(chuàng)建用戶的操作。但是還有一些數據并沒有用以處理數據,而是用以驗證的,比如下文的鑒權,可以將這些信息通過header進行傳輸,下方詳細展示。

4. 版本

API的開發(fā)直接關系了APP是否可以正常使用,如果原本運行正常的API,突然改動,那么之前使用這個API的APP可能無法正常運行。APP是不可能強迫用戶主動升級的,因此,通過API版本來解決這個問題。也就是說,API的多個版本是同時運行的,而且都要保證可以正常使用。

按照RESTful的規(guī)范,不同的版本也應該用相同的API URL,通過header信息來判斷版本,再調用不同版本的程序進行處理。但是這明顯會給開發(fā)帶來巨大的成本。解決辦法有兩種:1.新版本兼容舊版本,所有舊版本的動作、字段、操作,都在新版本中可以被實現,但明顯這樣的維護成本很大;2.不同的版本,用不同的URL來提供服務,比如再URL中通過v1、v2來區(qū)分版本號,我則更喜歡采用子域名的方式,比如v2.api.xxx.com/user的方式。

5. HTTP響應碼

在用戶發(fā)出請求,服務端對請求進行響應時,給予正確的HTTP響應狀態(tài)碼,有利于讓客戶端正確區(qū)分遇到的情況。

200 OK - [GET]:服務器成功返回用戶請求的數據,該操作是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
202 Accepted - [*]:表示一個請求已經進入后臺排隊(異步任務)
204 NO CONTENT - [DELETE]:用戶刪除數據成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發(fā)出的請求有錯誤,服務器沒有進行新建或修改數據的操作,該操作是冪等的。
401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。
403 Forbidden - [*] 表示用戶得到授權(與401錯誤相對),但是訪問是被禁止的。
404 NOT FOUND - [*]:用戶發(fā)出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的。
406 Not Acceptable - [GET]:用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 當創(chuàng)建一個對象時,發(fā)生一個驗證錯誤。
500 INTERNAL SERVER ERROR - [*]:服務器發(fā)生錯誤,用戶將無法判斷發(fā)出的請求是否成功。

6. 返回值結構

在完成了上面的URL部署之后,接下來我們來看看返回結果應該怎么樣來確定。我看到大部分文獻中指出,最好使用JSON進行返回,而非xml。我認為原因可能有兩點:1. JSON可以很好的被很多程序支持,javascript的ajax可以直接將JSON轉換為對象。2. JSON的格式在容量上比xml小很多,可以減低寬帶占用,提高傳輸效率。

那么,返回值應該怎么去部署呢?

首先,字段的合理返回,數據的包裹。因為返回值中,我們常常要對數據進行區(qū)分分組,或者按照從屬關系打包,所以,我們再返回時,最好有包裹的思想,把數據存放在不同的包裹中進行返回。

{
  "error_code" : 0,
  "data" : {
                   "user_id" : 1,
                   "username" : "xiaomin"
              },
  "server_time": 14939939
}

上面返回的JSON中,使用data來作為數據包,將所有數據統(tǒng)一以這個字段進行包裹。除了data,也可以用list等其他形式的包裹,命名都是自己來根據自己的需要確定的。

{
  "error_code" : 0,
  "list" : [
              {"user_id":1,"username":"xiaoming"},
              {"user_id":2,"username":"goudan"}
            ]
  "server_time": 14939939
}

總之,不要不分包,直接把所有數據和一些你想返回的全局數據混在一起進行返回。

其次,錯誤碼。錯誤碼的作用是方便查找錯誤原因,通常情況下,我喜歡用error_code來表示,當error_code=0時,表示沒有發(fā)生錯誤,當error_code>0時,發(fā)生了錯誤,并且提供較為詳細的文檔,告訴客戶端對應的error_code值所產生的錯誤的原因和位置。

最后,空白壓縮和字符轉換。也就是返回的JSON結果不要換行和空格,用一行返回結果,使整個結果文本容量最小。同時,中文等字符或結果中有引號,都進行字符轉換,防止結果無法被正確識別。

7. 鑒權

其實也就是客戶端的權限控制。一般而言,我會采用給客戶端分發(fā)一個token來確定該客戶端的唯一身份??蛻舳嗽谡埱髸r,通過這個token,判斷發(fā)出請求的客戶端所對應的用戶,及其相關信息和權限。

前文已經提到了,token信息不是用來進行處理的數據,雖然可以通過POST、PUT等進行數據提交或傳輸,但是從RESTful規(guī)范來講,它不屬于操作數據,在服務端進行處理時,僅是利用token進行鑒權處理,所以,我的建議是通過header來發(fā)送token。

 "xiaoming",
         "user_email" => "[email protected]"
    );
    // 添加apikey到header
    curl_setopt($ch, CURLOPT_HTTPHEADER  , $header);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    // 執(zhí)行HTTP請求
    curl_setopt($ch , CURLOPT_URL , $url);
    $res = curl_exec($ch);

    var_dump(json_decode($res));
?>

上面的代碼中,通過將CURLOPT_CUSTOMREQUEST設置為PUT,就可以發(fā)出PUT請求,發(fā)出的PUT請求,仍然需要通過CURLOPT_POSTFIELDS來傳輸數據。服務端接受PUT請求時,首先要對發(fā)出請求的客戶端進行token驗證,通過對token的處理,查找到擁有該token的實際用戶,從而確定了將對哪一個用戶進行信息更新操作。

國內大部分API對PUT、DELETE請求進行了閹割,更不用提HEAD、PACTH、OPTIONS請求。實際上,國內大部分開放API僅支持GET和POST兩種,部分API支持將app key信息通過header進行發(fā)送。在面對這種情況下,我們不得不拋棄標準的RESTful規(guī)范,在url中加入get、add、update、delete等動作詞匯,以補充由于請求支持不完善帶來的動作區(qū)分問題。如果僅支持GET和POST,那么所有需要保密的數據,絕對不可以用GET來進行請求,而必須用POST。

參考文獻

《理解RESTful架構》《RESTful API 設計指南》
《好RESTful API的設計原則》
《我所理解的RESTful Web API [設計篇]》
《https工作原理》

我的個人博客 www.tangshuang.net 偶爾寫一些學習中的感想和經驗,希望有相同興趣的朋友到博客來交流。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/21233.html

相關文章

  • 人人都是 API 設計師:我對 RESTful API、GraphQL、RPC API 思考

    摘要:通常情況下,偽都是基于第一層次與第二層次設計的。為了解決這個版本不兼容問題,在設計的一種實用的做法是使用版本號。例如,建議第三位版本號通常表示兼容升級,只有不兼容時才需要變更服務版本。 原文地址:梁桂釗的博客 博客地址:blog.720ui.com 歡迎關注公眾號:「服務端思維」。一群同頻者,一起成長,一起精進,打破認知的局限性。 有一段時間沒怎么寫文章了,今天提筆寫一篇自己對 API 設...

    ormsf 評論0 收藏0
  • 人人都是 API 設計師:我對 RESTful API、GraphQL、RPC API 思考

    摘要:通常情況下,偽都是基于第一層次與第二層次設計的。為了解決這個版本不兼容問題,在設計的一種實用的做法是使用版本號。例如,建議第三位版本號通常表示兼容升級,只有不兼容時才需要變更服務版本。 原文地址:梁桂釗的博客博客地址:http://blog.720ui.com 歡迎關注公眾號:「服務端思維」。一群同頻者,一起成長,一起精進,打破認知的局限性。 有一段時間沒怎么寫文章了,今天提筆寫一篇...

    FWHeart 評論0 收藏0
  • 貓頭鷹深夜翻譯:請不要把它叫做Restful!

    摘要:因此,誤解幾乎是與之俱來的。這是完全錯誤的。就像所強調的,對于一個被稱作的來說,狀態(tài)轉移管理是一個必須要完成的需求。你可以將其稱為或是,但是請不要把它叫做。 2000年的時候,Douglas Crockford聲明JavaScript是最被誤解的編程語言。這種誤解來源于不良的命名規(guī)范,錯誤設計,非標準模式等等。因此,誤解幾乎是與之俱來的。 我也在關于Restful架構上發(fā)表了一個相似的...

    dadong 評論0 收藏0
  • restful接口設計規(guī)范總結

    摘要:狀態(tài)碼狀態(tài)碼范圍信息,請求收到,繼續(xù)處理。范圍的狀態(tài)碼是保留給服務器端錯誤用的。當收到響應時,客戶端不可能知道服務器的狀態(tài),所以這類狀態(tài)碼是要盡可能的避免。服務器向用戶返回的狀態(tài)碼和提示信息,常見的有以下一些方括號中是該狀態(tài)碼對應的動詞。 這篇 文章主要是借鑒他人,但是自己很想總結出一套規(guī)范,以供向我這樣的新手使用,用來規(guī)范代碼,如果有什么好的提議,請不吝賜教,本篇文章長期更新! 一、...

    khs1994 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<