Python 构建 REST 风格接口 API
文章目錄
- 識別資源
- 定義您的接口
- 選擇數(shù)據(jù)交換格式
- 設(shè)計(jì)成功響應(yīng)
- GET
- POST
- PUT
- DELETE
- 設(shè)計(jì)錯誤響應(yīng)
識別資源
構(gòu)建 REST API 時,要采取的第一步是確定 API 將管理的資源。通常將這些資源描述為復(fù)數(shù)名詞,如customers 、events 、 或transactions 。在 Web 服務(wù)中標(biāo)識不同的資源時,您將構(gòu)建一個名詞列表,用于描述用戶可以在 API 中管理的不同數(shù)據(jù)。
執(zhí)行此操作時,請確保考慮任何嵌套資源。例如,customers 可能具有g(shù)uests或sales 可能包含events 。在定義 API 接口時,建立這些資源層次結(jié)構(gòu)將很有幫助。
定義您的接口
確定 Web 服務(wù)中的資源后,需要使用這些資源來定義 API 接口。以下是您可能在支付處理服務(wù)的 API 中找到的資源的一些示例接口:transactions
| GET | /transactions | 獲取交易列表。 |
| GET | /transactions/<transaction_id> | 獲取單個事務(wù)。 |
| POST | /transactions | 創(chuàng)建新事務(wù)。 |
| PUT | /transactions/<transaction_id> | 更新交易。 |
| PATCH | /transactions/<transaction_id> | 部分更新事務(wù)。 |
| DELETE | /transactions/<transaction_id> | 刪除交易記錄。 |
這六個節(jié)點(diǎn)涵蓋了在 Web 服務(wù)中transactions創(chuàng)建、讀取、更新和刪除所需的所有操作。Web 服務(wù)中的每個資源都將具有類似的節(jié)點(diǎn)列表,具體取決于用戶可以使用 API 執(zhí)行的操作。
注意: 節(jié)點(diǎn)不應(yīng)包含謂詞。相反,您應(yīng)該選擇適當(dāng)?shù)?HTTP 方法來傳達(dá)終結(jié)點(diǎn)的操作。例如,下面的終結(jié)點(diǎn)包含一個不需要的謂詞:
GET /getTransactions此處,get在不需要包含在接口中。HTTP 方法已通過指示操作為終結(jié)點(diǎn)提供語義含義。您可以從接口中刪除:GET
GET /transactions此接口僅包含一個復(fù)數(shù)名詞,HTTP GET 方法傳達(dá)操作。
現(xiàn)在看一下嵌套資源的接口示例。在這里,你將看到guests嵌套在資源events下的接口:
| GET | /events/<event_id>/guests | 獲取來賓列表。 |
| GET | /events/<event_id>/guests/<guest_id> | 獲取單個來賓。 |
| POST | /events/<event_id>/guests | 創(chuàng)建新的來賓。 |
| PUT | /events/<event_id>/guests/<guest_id> | 更新來賓。 |
| PATCH | /events/<event_id>/guests/<guest_id> | 部分更新來賓。 |
| DELETE | /events/<event_id>/guests/<guest_id> | 刪除來賓。 |
使用這些接口,可以管理系統(tǒng)中的特定事件。guests
這不是為嵌套資源定義接口的唯一方法。有些人更喜歡使用查詢字符串來訪問嵌套資源。查詢字符串允許您隨 HTTP 請求一起發(fā)送其他參數(shù)。在以下接口中,追加查詢字符串guests以獲取特定event_id:
GET /guests?event_id=23此節(jié)點(diǎn)guests將篩選出任何未引用給定event_id .與 API 設(shè)計(jì)中的許多事情一樣,您需要確定哪種方法最適合您的 Web 服務(wù)。
注意: REST API 不太可能在 Web 服務(wù)的整個生命周期中保持不變。資源將發(fā)生更改,您需要更新接口節(jié)點(diǎn)以反映這些更改。這就是 API 版本控制的用武之地。API 版本控制允許您修改 API,而不必?fù)?dān)心破壞現(xiàn)有集成。
有各種各樣的版本控制策略。選擇正確的選項(xiàng)取決于 API 的要求。以下是一些最受歡迎的 API 版本控制選項(xiàng):
- URI 版本控制
- HTTP 標(biāo)頭版本控制
- 查詢字符串版本控制
- 媒體類型版本控制
無論您選擇哪種策略,對 API 進(jìn)行版本控制都是確保其能夠適應(yīng)不斷變化的需求同時支持現(xiàn)有用戶的重要步驟。
選擇數(shù)據(jù)交換格式
用于格式化 Web 服務(wù)數(shù)據(jù)的兩個常用選項(xiàng)是 XML 和 JSON。傳統(tǒng)上,XML在[SOAP] API中非常流行,但JSON在REST API中更受歡迎。若要比較兩者,請看一個格式化為 XML 和 JSON 的示例資源book。
下面是一本格式化為 XML 的書:
<?xml version="1.0" encoding="UTF-8" ?> <book><title>Python Basics</title><page_count>635</page_count><pub_date>2021-03-16</pub_date><authors><author><name>David Amos</name></author><author><name>Joanna Jablonski</name></author><author><name>Dan Bader</name></author><author><name>Fletcher Heisler</name></author></authors><isbn13>978-1775093329</isbn13><genre>Education</genre> </book>XML 使用一系列元素對數(shù)據(jù)進(jìn)行編碼。每個元素都有一個開始和結(jié)束標(biāo)記,數(shù)據(jù)介于兩者之間。元素可以嵌套在其他元素中。您可以在上面看到這一點(diǎn),其中幾個標(biāo)記嵌套在 .<author>``<authors>
現(xiàn)在,看看JSON中的相同內(nèi)容:book
{"title": "Python Basics","page_count": 635,"pub_date": "2021-03-16","authors": [{"name": "David Amos"},{"name": "Joanna Jablonski"},{"name": "Dan Bader"},{"name": "Fletcher Heisler"}],"isbn13": "978-1775093329","genre": "Education" }JSON將數(shù)據(jù)存儲在類似于Python字典的鍵值對中。與 XML 一樣,JSON 支持將數(shù)據(jù)嵌套到任何級別,因此您可以對復(fù)雜數(shù)據(jù)進(jìn)行建模。
JSON和XML本質(zhì)上都不比另一個更好,但REST API開發(fā)人員更喜歡JSON。當(dāng)
您將 REST API 與 React 或 Vue 等前端框架配對時,尤其如此。
設(shè)計(jì)成功響應(yīng)
選擇數(shù)據(jù)格式后,下一步是確定如何響應(yīng) HTTP 請求。來自 REST API 的所有響應(yīng)都應(yīng)具有類似的格式,并包含正確的 HTTP 狀態(tài)代碼。
在本節(jié)中,您將查看管理cars 清單 的假設(shè) API 的一些示例 HTTP 響應(yīng)。這些示例將讓您了解應(yīng)如何設(shè)置 API 響應(yīng)的格式。為了清楚起見,您將查看原始HTTP請求和響應(yīng),而不是使用像.requests
要開始操作,請查看GET 對 /cars的請求,其中返回以下列表:
GET /cars HTTP/1.1 Host: api.example.com此 HTTP 請求由四部分組成:
GET
這四個部分是您向/cars 發(fā)送GET請求所需的全部內(nèi)容。現(xiàn)在來看看響應(yīng)。此 API 使用 JSON 作為數(shù)據(jù)交換格式:
HTTP/1.1 200 OK Content-Type: application/json ...[{"id": 1,"make": "GMC","model": "1500 Club Coupe","year": 1998,"vin": "1D7RV1GTXAS806941","color": "Red"},{"id": 2,"make": "Lamborghini","model":"Gallardo","year":2006,"vin":"JN1BY1PR0FM736887","color":"Mauve"},{"id": 3,"make": "Chevrolet","model":"Monte Carlo","year":1996,"vin":"1G4HP54K714224234","color":"Violet"} ]該 API 返回一個響應(yīng),其中包含cars 的列表。您知道由于狀態(tài)代碼200 OK的原因,響應(yīng)成功。響應(yīng)的標(biāo)頭Content-Type還設(shè)置為application/json 。這告訴用戶將響應(yīng)解析為 JSON。
注意: 當(dāng)您使用真正的API時,您將看到比這更多的HTTP標(biāo)頭。這些標(biāo)頭在 API 之間有所不同,因此在這些示例中已排除它們。
請務(wù)必始終在響應(yīng)上設(shè)置正確的標(biāo)頭Content-Type。如果發(fā)送 JSON,Content-Type則設(shè)置為application/json 。如果為 XML,則將其設(shè)置為 application/xml。此標(biāo)頭告訴用戶應(yīng)如何分析數(shù)據(jù)。
您還希望在響應(yīng)中包含適當(dāng)?shù)臓顟B(tài)代碼。對于任何成功的請求,GET應(yīng)返回200 OK 。這告訴用戶其請求已按預(yù)期處理。
看看另一個GET請求,這次是針對一輛車:
GET /cars/1 HTTP/1.1 Host: api.example.com此 HTTP 請求查詢汽車1的 API。以下是響應(yīng):
HTTP/1.1 200 OK Content-Type: application/json{"id": 1,"make": "GMC","model": "1500 Club Coupe","year": 1998,"vin": "1D7RV1GTXAS806941","color": "Red" },此響應(yīng)包含帶有汽車數(shù)據(jù)的單個 JSON 對象。由于它是單個對象,因此不需要將其包裝在列表中。與上一個響應(yīng)一樣,這也有一個狀態(tài)代碼。200 OK
注意: 請求永遠(yuǎn)不應(yīng)修改現(xiàn)有資源。如果請求包含數(shù)據(jù),則應(yīng)忽略此數(shù)據(jù),并且 API 應(yīng)返回未更改的資源。GET
POST
接下來,查看添加新車的請求:POST
POST /cars HTTP/1.1 Host: api.example.com Content-Type: application/json{"make": "Nissan","model": "240SX","year": 1994,"vin": "1N6AD0CU5AC961553","color": "Violet" }此POST請求在請求中包含新車的 JSON。它將標(biāo)頭Content-Type設(shè)置為application/json以便 API 知道請求的內(nèi)容類型。API 將從 JSON 創(chuàng)建新汽車。
以下是響應(yīng):
HTTP/1.1 201 Created Content-Type: application/json{"id": 4,"make": "Nissan","model": "240SX","year": 1994,"vin": "1N6AD0CU5AC961553","color": "Violet" }此響應(yīng)具有狀態(tài)代碼200 OK,201 Created用于告知用戶已創(chuàng)建新資源。201 Created確保對所有成功的請求使用 而不是POST 。
此響應(yīng)還包括新車的副本id,其中包含由 API 生成的id請務(wù)必在響應(yīng)中發(fā)回 a,以便用戶可以再次修改資源。
注意: 當(dāng)用戶使用 POST或PUT 或PATCH 修改資源時,始終發(fā)回資源的副本非常重要。這樣,用戶就可以看到他們所做的更改。
PUT
現(xiàn)在看一下請求:PUT
PUT /cars/4 HTTP/1.1 Host: api.example.com Content-Type: application/json{"make": "Buick","model": "Lucerne","year": 2006,"vin": "4T1BF3EK8AU335094","color":"Maroon" }此請求使用上一個請求中的id 使用PUT所有新數(shù)據(jù)更新汽車。提醒一下,請使用新數(shù)據(jù)更新資源上的所有字段。以下是響應(yīng):
HTTP/1.1 200 OK Content-Type: application/json{"id": 4,"make": "Buick","model": "Lucerne","year": 2006,"vin": "4T1BF3EK8AU335094","color":"Maroon" }響應(yīng)包括具有新數(shù)據(jù)的car 的副本。同樣,您始終希望PUT發(fā)回請求的完整資源。這同樣適用于PATCH請求:
PATCH /cars/4 HTTP/1.1 Host: api.example.com Content-Type: application/json{"vin": "VNKKTUD32FA050307","color": "Green" }PATCH請求僅更新資源的一部分。在上面的請求中,vin和color 字段將使用新值進(jìn)行更新。以下是響應(yīng):
HTTP/1.1 200 OK Content-Type: application/json{"id": 4,"make": "Buick","model": "Lucerne","year": 2006,"vin": "VNKKTUD32FA050307","color": "Green" }響應(yīng)包含 car的完整副本。如您所見,只有vin 和color 字段已更新。
DELETE
最后,看看 REST API 在收到DELETE請求時應(yīng)如何響應(yīng)。下面是刪除 :
HTTP/1.1 204 No Content此響應(yīng)僅包括狀態(tài)代碼 。此狀態(tài)代碼204 No Content告訴用戶操作成功,但響應(yīng)中未返回任何內(nèi)容。這是有道理的,因?yàn)閏ar 已被刪除。沒有理由在響應(yīng)中將其副本發(fā)送回去。
設(shè)計(jì)錯誤響應(yīng)
對 REST API 的請求總是有可能失敗。最好定義錯誤響應(yīng)的外觀。這些響應(yīng)應(yīng)包括所發(fā)生錯誤的說明以及相應(yīng)的狀態(tài)代碼。在本節(jié)中,您將看幾個示例。
首先,請查看對 API 中不存在的資源的請求:
GET /motorcycles HTTP/1.1 Host: api.example.com此處,用戶向/motorcycles 發(fā)送不存在的請求。API 會發(fā)回以下響應(yīng):
HTTP/1.1 404 Not Found Content-Type: application/json ...{"error": "The requested resource was not found." }此響應(yīng)包括狀態(tài)代碼。除此之外,響應(yīng)還包含一個帶有描述性錯誤消息的 JSON 對象。提供描述性錯誤消息可為用戶提供有關(guān)錯誤的更多上下文。
現(xiàn)在看一下用戶發(fā)送無效請求時的錯誤響應(yīng):
POST /cars HTTP/1.1 Host: api.example.com Content-Type: application/json{"make": "Nissan","year": 1994,"color": "Violet"此POST請求包含 JSON,但格式不正確。它缺少末尾的右大括號 (})。API 將無法處理此數(shù)據(jù)。錯誤響應(yīng)會告知用戶以下問題:
HTTP/1.1 400 Bad Request Content-Type: application/json{"error": "This request was not properly formatted. Please send again." }此響應(yīng)包括一條描述性錯誤消息以及狀態(tài)代碼,告知用戶他們需要修復(fù)請求。
還有其他幾種方式,即使請求的格式正確,也可能是錯誤的。在下一個示例中,用戶發(fā)送請求,但包含不受支持的媒體類型:POST
POST /cars HTTP/1.1 Host: api.example.com Content-Type: application/xml<?xml version="1.0" encoding="UTF-8" ?> <car><make>Nissan</make><model>240SX</model><year>1994</year><vin>1N6AD0CU5AC961553</vin><color>Violet</color> </car>在此請求中,用戶發(fā)送 XML,但 API 僅支持 JSON。該 API 的響應(yīng)方式如下:
HTTP/1.1 415 Unsupported Media Type Content-Type: application/json{"error": "The application/xml mediatype is not supported." }此響應(yīng)包括狀態(tài)代碼,以指示請求包含 API 不支持的數(shù)據(jù)格式。此錯誤代碼對于格式錯誤的數(shù)據(jù)有意義,但是即使格式正確也無效的數(shù)據(jù)呢?
在下一個示例中,用戶發(fā)送請求,但包含的數(shù)據(jù)與其他數(shù)據(jù)的字段不匹配:
POST /cars HTTP/1.1 Host: api.example.com Content-Type: application/json{"make": "Nissan","model": "240SX","topSpeed": 120"warrantyLength": 10 }在此請求中,用戶向 JSON 添加topSpeed和warrantyLength字段。API 不支持這些字段,因此它會以錯誤消息進(jìn)行響應(yīng):
HTTP/1.1 422 Unprocessable Entity Content-Type: application/json{"error": "Request had invalid or missing data." }此響應(yīng)包括狀態(tài)代碼。此狀態(tài)代碼表示請求沒有任何問題,但數(shù)據(jù)無效。REST API 需要驗(yàn)證傳入的數(shù)據(jù)。如果用戶隨請求一起發(fā)送數(shù)據(jù),則 API 應(yīng)驗(yàn)證數(shù)據(jù)并通知用戶任何錯誤。
響應(yīng)請求(無論是成功的還是錯誤的)是 REST API 最重要的工作之一。如果您的 API 直觀且提供準(zhǔn)確的響應(yīng),則用戶將更容易圍繞您的 Web 服務(wù)構(gòu)建應(yīng)用程序。幸運(yùn)的是,一些優(yōu)秀的Python Web框架抽象出了處理HTTP請求和返回響應(yīng)的復(fù)雜性。
總結(jié)
以上是生活随笔為你收集整理的Python 构建 REST 风格接口 API的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记录的一些本网站上网友推荐的外国网址
- 下一篇: Python爬虫爬取表情包+Autojs