<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 什么是 RESTful ? REST 全稱是 Representational State Transfer,中文意思是表述性狀態轉移(注:通常譯為表征性狀態轉移)。 它首次出現在 2000 年 Roy Fielding 的博士論文中,Roy Fielding 是 HTTP 規范的主要編寫者之一。 Roy Fielding 在論文中提到:“我這篇文章的寫作目的,就是想在**符合架構原理的前提下,理解和評估以網絡為基礎的應用軟件的架構設計,得到一個功能強、性能好、適宜通信的架構**。REST 指的是一組架構約束條件和原則。” 如果一個架構符合 REST 的約束條件和原則,我們就可以稱之為 RESTful 架構。 通俗地講:**RESTful 就是客戶端與服務器進行數據交互的一種規范**,而且是當今**絕大多數開發者都在遵循的規范**。 應用 RESTful 架構,可以想像成讀者去圖書館找書,讀者相當于客戶端,圖書館相當于服務器。不同種類的書籍,對應不同分類,且有固定的分類縮寫。如編號以 T 開頭的圖書,表示工業技術類圖書,編號以 J 開頭的圖書,表示藝術類圖書。不管去哪一個圖書館,這些分類縮寫都是相同的,任何一位讀者只要知道圖書種類,就可在標有相應分類縮寫的書架區域找到相應書籍。**RESTful 就是 Web 開發行業的規范,符合這種規范,就是一套 RESTful 架構**。 ## 為什么學習RESTful? 近年來,**隨著前后端分離技術的普遍應用,API 接口技術已經成為前后端開發人的必修課之一**。在業內,**不論使用什么編程語言開發 API,都需要遵守 RESTful 規范**。因此,不論你是使用 API 的前端開發人員,還是直接開發 API 接口的后端開發人員,都必須熟悉 RESTful Web 規范,否則將很難同其他人配合。 ## 如何學習RESTful ? 我們通過理論介紹加動手實踐的方式完成 RESTful Web 的學習。實踐環節,我們選用 Django Rest framework 框架帶領讀者親自搭建一套 RESTful 架構的 API。Django Rest framework 是基于 Django 框架開發的**用來幫助開發者快速構建 RESTful Web API 的強大而又靈活的工具**。在實現 API 的過程中,Django Rest framework 為我們實現了大量的操作,使用該框架僅需書寫少量代碼,就可實現 API 的構建,大大減少了工作量,**可使開發者將更多精力集中在 API 的設計**,而非 API 的實現工程。 ## RESTful設計方法和規范 在初步了解了 RESTful 之后,我們接到一項任務,需要為一所學校開發一套師生管理系統,客戶要求所開發的系統能在 PC 桌面通過瀏覽器使用,而且日后還想開發 IOS 和 Android 應用。了解需求之后,我們毫不猶豫選擇了前后端分離的開發模式,并且決定遵從時下最為流行的 RESTful 規范。接下來,我們就以后端開發人員的角色,一起來了解整個開發過程。 ### 1\. 域名(Domain) 根據 RESTful 規范,應該盡量使用專用的域名用于部署 API,于是我們和校方溝通,使用下方域名作為 API 訪問地址: ~~~http https://api.demo.com ~~~ 但是經過溝通,發現上述域名已被占用,校方否決了我們的提議,考慮到 API 相對簡單,于是我們使用下面地址部署 API: ~~~http https://www.demo.com/api ~~~ 上述地址中,**https**代表協議名稱,常見的還有**http**,二者區別在于前者在傳輸過程中是將信息加密后傳輸的,而后者是明文傳輸;**[www.demo.com](http://www.demo.com/)**為域名,可以理解成某個機房里一臺電腦的地址,通過這個地址,就能訪問這臺電腦提供的資源;**api**代表一個資源路徑,可以想象成這臺電腦中一個文件夾的路徑。 ### 2\. 版本(Versioning) 師生管理系統不是一成不變的,日后還要更新維護。為了區分不同版本,API 的 URL 中應當包含 API 版本信息: ~~~http http://www.demo.com/api/1.0/foo http://www.demo.com/api/1.1/foo http://www.demo.com/api/2.0/foo ~~~ 除了上述方法外,API 版本信息還可放在 HTTP 請求頭中。[Github](https://developer.github.com/v3/media/#request-specific-version)采用的就是這種做法。 因為不同的版本,可以理解成同一種資源的不同表現形式,所以應該采用同一個 URL。版本號可以在 HTTP 請求頭信息的 Accept 字段中進行區分(參見[Versioning REST Services](http://www.informit.com/articles/article.aspx?p=1566460)): ~~~http 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 ~~~ 實際工作中,通常采用第一種方法,因為這樣的方式更加直觀,方便使用。 ### 3\. 路徑(Endpoint) 路徑即"終點"(endpoint),是訪問 API 的具體網址,通過訪問每個網址,可以獲取到相應的資源(resource)。在師生管理系統中,所謂資源,就是我們想獲取的信息,比如獲取 3 年 2 班所有學生姓名,獲取小明的年齡、成績等。 路徑須滿足以下規范: **1\. 資源路徑中應當使用名詞,杜絕動詞。資源路徑中的名詞,應當與數據庫的表名相對應。** 以下路徑中包含動詞,是不符合規范的例子,在實際工作中,應當避免。 ~~~http /getStudents :獲取學生信息 /listTeachers :獲取老師信息 /retreiveStudentByID?Id=2020 :獲取ID為2020的學生信息 ~~~ 對于資源的操作,應該通過 HTTP 中的不同方法來區分處理資源的動作,資源路徑中應當只包含名詞。 ~~~http GET /students :將返回所有學生信息 POST /students :將新增的學生信息存入數據庫 GET /students/4 :獲取編號為4號的學生信息 PATCH(或)PUT /students/4 :更新編號為4的學生信息 ~~~ **2\. API 中的名詞應該使用復數。無論是子資源或者是所有資源。** 例如: ~~~http 獲取單個學生信息:http://www.demo.com/students/1 :獲取編號為1的學生信息 獲取所有學生信息: http://www.demo.com/students :獲取所有學生信息 ~~~ ### 4\. HTTP動詞 對于資源的具體操作類型,由 HTTP 動詞表示。 常用的 HTTP 動詞有下面 4 個(括號里是對應的 SQL 命令)。 * **GET(SELECT)**:從服務器取出資源(一項或多項) * **POST(CREATE)**:在服務器新建一個資源 * **PUT(UPDATE)**:在服務器更新資源(客戶端提供改變后的完整資源) * **DELETE(DELETE)**:從服務器刪除資源 還有 3 個不常用的 HTTP 動詞。 * **PATCH(UPDATE)**:在服務器更新(更新)資源(客戶端提供改變的屬性) * **HEAD**:獲取資源的元數 * **OPTIONS**:獲取信息,關于資源的哪些屬性是客戶端可以改變的 下面是一些例子。 ~~~http GET /classes:列出所有班級 POST /classes:新建一個班級(上傳文件) GET /classes/ID:獲取某個指定班級的信息 PUT /classes/ID:更新某個指定班級的信息(提供該班級的全部信息) PATCH /classes/ID:更新某個指定班級的信息(提供該班級的部分信息) DELETE /classes/ID:刪除某個班級 GET /classes/ID/students:列出某個指定班級的所有學生 DELETE /classes/ID/students/ID:刪除某個指定班級的指定學生 ~~~ ### 5\. 過濾信息(Filtering) 如果記錄數量很多,服務器不可能都將它們返回給用戶。API 應該提供參數,過濾返回結果。比如,我們想獲取全校師生的個人信息,如果將這些信息一股腦地全部展示在網頁上,是不明智也是不現實的。如果數據量太大,在實際開發中我們會采用分頁展示的形式。另外,如果想在一次考試后,按照成績高低展示學生信息,那么可以通過過濾信息來實現。 所謂過濾,就是在 URL 中添加一下限制參數。下面是一些常見的參數。 ~~~http ?limit=10:指定返回記錄的數量 ?offset=10:指定返回記錄的開始位置。 ?page=2&per_page=100:指定第幾頁,以及每頁的記錄數。 ?sortby=score&order=asc:指定返回結果按照學生的成績(score)正序(asc)排列順序。 ~~~ 參數的設計允許存在冗余,即允許 API 路徑和 URL 參數允許有重復。比如,想要查詢某個班級所有學生信息,我們可以設計`GET /classes/ID/students`與`GET /students?class_id=ID`兩種地址,任何一種都可得到相同的結果。 ### 6\. 狀態碼(Status Codes) 服務器向用戶返回的狀態碼和提示信息,常見的有以下一些(方括號中是該狀態碼對應的 HTTP 動詞)。不同的狀態碼代表著不同的含義,比如以 2 開頭的狀態碼通常代表服務器成功響應,3 開頭的狀態碼代表發生了重定性(即跳轉到了別的鏈接),4 開頭的狀態碼通常表示客戶端這邊提供的信息有誤,而 5 開頭的狀態碼則表示服務器內部出現的錯誤。通過返回的狀態碼,用戶即可判斷請求成功與否,不成功問題在何處。 一些常用的狀態碼列舉如下: * **200 OK - \[GET\]**:服務器成功返回用戶請求的數據 * **201 CREATED - \[POST/PUT/PATCH\]**:用戶新建或修改數據成功。 * **202 Accepted - \[\*\]**:表示一個請求已經進入后臺排隊(異步任務) * **204 NO CONTENT - \[DELETE\]**:用戶刪除數據成功 * **400 INVALID REQUEST - \[POST/PUT/PATCH\]**:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操作 * **401 Unauthorized - \[\*\]**:表示用戶沒有權限(令牌、用戶名、密碼錯誤) * **403 Forbidden - \[\*\]**表示用戶得到授權(與401錯誤相對),但是訪問是被禁止的 * **404 NOT FOUND - \[\*\]**:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的 * **406 Not Acceptable - \[GET\]**:用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式) * **410 Gone -\[GET\]**:用戶請求的資源被永久刪除,且不會再得到的 * **422 Unprocesable entity - \[POST/PUT/PATCH\]**: 當創建一個對象時,發生一個驗證錯誤 * **500 INTERNAL SERVER ERROR - \[\*\]**:服務器發生錯誤,用戶將無法判斷發出的請求是否成功 狀態碼的完全列表參見[這里](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)或[這里](https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81)。 ### 7\. 錯誤信息 如果狀態碼是 4xx,服務器就應該向用戶返回出錯信息。一般來說,返回的信息是鍵值對形式的數據,將`error`作為鍵名,出錯信息作為鍵值即可。比如,在一個提供查詢學生信息的 API 中,要求客戶端提供正確的 API key(可以理解為輸入了正確的用戶名和密碼)才能訪問,如果提供的 API key 不正確,此時服務器應拒絕訪問,并返回錯誤信息。這樣,客戶端就知道了為何沒能查到信息,修改成正確的 API key 即可。 ~~~json { error: "Invalid API key" } ~~~ ### 8\. 返回結果 針對不同操作,服務器向用戶返回的結果應該符合以下規范。 * **GET /collection**:返回資源對象的列表(數組) * **GET /collection/resource**:返回單個資源對象 * **POST /collection**:返回新生成的資源對象 * **PUT /collection/resource**:返回完整的資源對象 * **PATCH /collection/resource**:返回完整的資源對象 * **DELETE /collection/resource**:返回一個空文檔 ### 9\. 超媒體鏈接 RESTful API 最好做到 Hypermedia(即返回結果中提供鏈接,連向其他 API 方法),使得用戶不查文檔,也知道下一步應該做什么。 比如,Github 的 API 就是這種設計,訪問[api.github.com](https://api.github.com/)會得到一個所有可用API的網址列表。 ~~~json { "current_user_url": "https://api.github.com/user", "authorizations_url": "https://api.github.com/authorizations", // ... } ~~~ 從上面可以看到,如果想獲取當前用戶的信息,應該去訪問[api.github.com/user](https://api.github.com/user),然后就得到了下面結果。 ~~~json { "message": "Requires authentication", "documentation_url": "https://developer.github.com/v3" } ~~~ 上面代碼表示,服務器給出了提示信息,以及文檔的網址。 ### 10\. 數據格式 服務器返回的數據格式,應該盡量使用 JSON,避免使用 XML。什么是 JSON 呢?什么又是 XML 呢?兩種數據格式的簡單舉例如下: ~~~json # JSON {"name":"XiaoMing", "age":"12", "gender":"male"} ~~~ ~~~xml # XML <?xml version="1.0" encoding="UTF-8" ?> <name>XiaoMing</name> <age>12</age> <gender>male</gender> ~~~ 通過上面的對比可以看出,JSON 數據形式要遠比 XML 的數據形式來得簡單和易懂,所以現在的 Web 開發中 JSON 數據格式已經開始全面取代 XML 應用在實際開發中。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看