想象一下,一個(gè)開發(fā)人員團(tuán)隊(duì)正在開發(fā)適用于iOS和Android的移動應(yīng)用程序,并且需要一個(gè)RESTful Web服務(wù)來執(zhí)行toys的CRUD操作。 我們確定不想使用模擬Web服務(wù),并且不想花費(fèi)時(shí)間來選擇和配置ORM(對象關(guān)系映射的簡稱)。 我們希望快速構(gòu)建一個(gè)RESTful Web服務(wù),并盡快準(zhǔn)備好開始在移動應(yīng)用程序中與它進(jìn)行交互。
我們希望toys能夠存儲在數(shù)據(jù)庫中,但我們還不準(zhǔn)備立即把它用在生產(chǎn)環(huán)境中。 因此,我們可以使用最簡單的關(guān)系數(shù)據(jù)庫,這樣我們就不必花太多時(shí)間執(zhí)行復(fù)雜的安裝或配置。
Django REST框架(也稱為DRF)將允許我們輕松完成此任務(wù),并開始向我們的RESTful Web服務(wù)的第一個(gè)版本發(fā)出HTTP請求。 在這種情況下,我們將使用一個(gè)非常簡單的SQLite數(shù)據(jù)庫,這是一個(gè)新的Django REST框架項(xiàng)目的默認(rèn)數(shù)據(jù)庫。
首先,我們必須指定主要資源的要求:一個(gè) ‘toy’。 我們需要toy實(shí)體的以下屬性或字段:
- 整數(shù)標(biāo)識符
- 一個(gè)名字
- 可選的描述
- 玩具類別描述,例如動作人物,玩偶或玩具
- 發(fā)布日期
- 一個(gè)bool值,表示玩具是否已經(jīng)在網(wǎng)上商店的主頁上至少一次
此外,我們希望有一個(gè)時(shí)間戳,其中包含玩具添加到數(shù)據(jù)庫表中的日期和時(shí)間。
在RESTful Web服務(wù)中,每個(gè)資源都有自己唯一的URL。 在我們的網(wǎng)絡(luò)服務(wù)中,每個(gè)玩具都有自己唯一的URL。
注:下面所說的http請求方法即 GET,PUT,POST,DELETE等
下表顯示了我們的第一個(gè)Web服務(wù)版本需要支持的方法,HTTP 請求方法,作用范圍和和含義。 每個(gè)方法都由HTTP 請求方法和范圍組成。 所有方法對toy和集合都有明確的含義:
| HTTP verb | Scope | Semantics |
|---|---|---|
| GET | Toy | 請求單個(gè)數(shù)據(jù) |
| GET | Collection of toys | 取回所有存儲在數(shù)據(jù)庫中的toy數(shù)據(jù),并根據(jù)名字按照升序排列 |
| POST | Collection of toys | 創(chuàng)建一個(gè)新的toy |
| PUT | Toy | 更新一個(gè)已經(jīng)存在的toy |
| DELETE | Toy | 刪除一個(gè)toy |
在上表中,GET 出現(xiàn)兩次,但有兩個(gè)不同的范圍:toys 和collection of toys。 第一個(gè)顯示應(yīng)用于玩具的GET,即請求單個(gè)資源。 第二行顯示應(yīng)用于玩具集合的GET,即應(yīng)用于資源集合的請求。
我們希望我們的Web服務(wù)能夠區(qū)分URL中集合的單個(gè)資源。 當(dāng)我們引用一個(gè)集合時(shí),我們將使用斜杠(/)作為URL的最后一個(gè)字符,如http:// localhost:8000 / toys /。 當(dāng)我們引用單個(gè)資源時(shí)我們不會使用斜杠(/)作為URL的最后一個(gè)字符,如http:// localhost:8000 / toys / 5。
讓我們考慮一下http:// localhost:8000 / toys /是玩具集合的URL。 如果我們在前一個(gè)URL中添加一個(gè)數(shù)字,我們會識別一個(gè)ID或主鍵等于指定數(shù)值的特定玩具。 例如,http:// localhost:8000 / toys / 42,標(biāo)識了ID等于42的玩具。
POST
我們必須使用POST方法和http:// localhost:8000 / toys / request URL編寫和發(fā)送HTTP請求,以創(chuàng)建新toy并將其添加到toys集合中。 在此示例中,我們的RESTful Web服務(wù)將使用JSON(JavaScript Object Notation的簡稱),因此我們必須提供帶有字段名稱和值的JSON鍵值對來創(chuàng)建新玩具。 作為請求的結(jié)果,服務(wù)器將驗(yàn)證字段的提供值,確保它是一個(gè)有效的toy,并將其保存在數(shù)據(jù)庫中。 服務(wù)器將在適當(dāng)?shù)谋碇胁迦霂в行峦婢叩男滦?,然后將返?01 Created狀態(tài)代碼和一個(gè)帶有剛剛添加成功的并且序列化為JSON的toy數(shù)據(jù),該JSON數(shù)據(jù)包括由數(shù)據(jù)庫自動生成并分配ID和toy對象:
POST http:// localhost:8000 / toys /
GET
我們需要使用GET方法和http:// localhost:8000 / toys / {id}的請求 URL來發(fā)送HTTP請求,以檢索ID與{id}中指定數(shù)值匹配的玩具。 例如,如果我們使用請求URL http:// localhost:8000 / toys / 25,服務(wù)器將檢索ID為25的玩具。作為請求的結(jié)果,服務(wù)器將從中檢索具有指定ID的玩具。作為請求的結(jié)果,服務(wù)器將從數(shù)據(jù)庫中檢索具有指定ID的玩具,并用Python創(chuàng)建適當(dāng)?shù)膖oy對象。如果找到玩具,服務(wù)器會將toy對象序列化為JSON,返回200 OK狀態(tài)代碼,并返回帶有序列化toy對象的JSON正文。如果沒有玩具與指定的ID匹配,則服務(wù)器將僅返回404 Not Found狀態(tài):
GET http:// localhost:8000 / toys / {id}
PUT
我們需要使用PUT方法,來編寫并發(fā)送HTTP請求,并請求URLhttp:// localhost:8000 / toys / {id},通過檢索ID與{id}中的值匹配的玩具,然后用提供的數(shù)據(jù)來替換它。此外,我們還需要提供帶有字段名稱和值的JSON鍵值對,來創(chuàng)建并替換現(xiàn)有玩具的新玩具。作為請求的結(jié)果,服務(wù)器將驗(yàn)證字段的提供值,確保它是有效玩具,然后用新的數(shù)據(jù)替換匹配ID的toy。更新操作后,玩具的ID將相同。服務(wù)器將更新相應(yīng)表中的現(xiàn)有行,它將返回200 OK狀態(tài)代碼和JSON主體如果我們沒有為新玩具提供所有必要字段,服務(wù)器將返回400 Bad Request狀態(tài)代碼。如果服務(wù)器找不到具有指定ID的玩具,則服務(wù)器將僅返回404未找到狀態(tài):
PUT http:// localhost:8000 / toys / {id}
DELETE
我們需要使用DELETE 方法 ,來編寫并發(fā)送HTTP請求,并請求URLhttp:// localhost:8000 / toys / {id}以刪除ID與{id}中指定數(shù)字值匹配的玩具。例如,如果我們通過請求URL http:// localhost:8000 / toys / 34,服務(wù)器將刪除ID為34的玩具。作為請求的結(jié)果,服務(wù)器將從數(shù)據(jù)庫中檢索具有指定ID的玩具并在Python中創(chuàng)建適當(dāng)?shù)耐婢邔ο蟆?如果找到玩具,服務(wù)器將請求ORM刪除與此玩具對象關(guān)聯(lián)的玩具行,并且服務(wù)器將返回204 No Content狀態(tài)代碼。 如果沒有玩具與指定的ID匹配,則服務(wù)器將僅返回404 Not Found狀態(tài):
DELETE http:// localhost:8000 / toys / {id}