標籤:python web服務 api
Eve是一款Python的REST API架構,用於發布高可定製的、全功能的RESTful的Web服務,幫你輕鬆建立和部署API,本文翻譯自Eve官方網站:
http://python-eve.org/quickstart.html#database-interlude
Eve 快速入門:
渴望開始嗎?這個頁面將提供Eve一個很好的介紹。在這之前假設:
你已經安裝好了Eve。如果你還沒有,可以點擊到安裝頁面。
已經安裝了MongoDB。
並且MongoDB 已經運行了。
一個最小的應用
一個最小的Eve應用,看起來是這樣的:
from eve import Eveapp = Eve()if __name__ == ‘__main__‘: app.run()
然後儲存為run.py,接著建立一個新的文檔包含已經內容:
DOMAIN = {‘people‘: {}}
接著儲存為settings.py,並且放在run.py相同的檔案夾下。
這是Eve的設定檔,一個標準的python模組,這個檔案告訴了Eve你的API包含了一個可訪問的資源,people。
現在你已經準備好啟動你的API了。
$ python run.py * Running on http://127.0.0.1:5000/
現在你已經可以使用這個API了:
$ curl -i http://127.0.0.1:5000HTTP/1.0 200 OKContent-Type: application/jsonContent-Length: 82Server: Eve/0.0.5-dev Werkzeug/0.8.3 Python/2.7.3Date: Wed, 27 Mar 2013 16:06:44 GMT
恭喜,你的GET請求已經得到了一個很好的響應返回,讓我們看看這個承載:
{ "_links": { "child": [ { "href": "people", "title": "people" } ] }}
API存取點遵循著HATEOAS(超媒體即狀態應用引擎)原則和規定API資源訪問資訊,在我們的例子中只提供了一個可用child的資源,這裡是people。
現在嘗試請求people:
{ "_items": [], "_links": { "self": { "href": "people", "title": "people" }, "parent": { "href": "/", "title": "home" } }}
這次我們也得到了一個_items 表,_links 相對於是被訪問的資源,所以你得到了父資源連結(首頁)和資源本身。
預設情況下Eve 的APIs是唯讀:
$ curl -X DELETE http://127.0.0.1:5000/people<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><title>405 Method Not Allowed</title><h1>Method Not Allowed</h1><p>The method DELETE is not allowed for the requested URL.</p>
這是因為我們還沒有在settings.py中規定任何的資料庫細節,所以Eve會在無法索引到任何people表實際的內容(甚至可能不存在)時無縫得提供一個空的資源,因為我們不想讓API的使用者down(不知道譯成什麼好…)。
插入資料庫
讓我們通過增加下面幾行到setting.py來串連資料庫:
# Let‘s just use the local mongod instance. Edit as needed.# Please note that MONGO_HOST and MONGO_PORT could very well be left# out as they already default to a bare bones local ‘mongod‘ instance.MONGO_HOST = ‘localhost‘MONGO_PORT = 27017MONGO_USERNAME = ‘user‘MONGO_PASSWORD = ‘user‘MONGO_DBNAME = ‘apitest‘
由於MongoDB便捷性,我們不需要真正得去建立資料表,實際上我們甚至不需要建立資料庫:GET 請求空的或不存在的資料庫是會返回正確(200 OK會得到一個空集合(表));DELETE/PATCH/PUT會得到適當的響應(404 Not Found),POST請求會建立所需的資料庫或表。然而這樣的自動管理的資料庫會執行得非常差,因為缺少了索引和任何形式的最佳化。
一個更複雜的應用
到目前為止我們的API都是唯讀,讓我們能夠全面得進行CRUD(增加(Create)、讀取(Retrieve)(重新得到資料)、更新(Update)和刪除(Delete))運作:
# Enable reads (GET), inserts (POST) and DELETE for resources/collections# (if you omit this line, the API will default to [‘GET‘] and provide# read-only access to the endpoint).RESOURCE_METHODS = [‘GET‘, ‘POST‘, ‘DELETE‘]# Enable reads (GET), edits (PATCH), replacements (PUT) and deletes of# individual items (defaults to read-only item access).ITEM_METHODS = [‘GET‘, ‘PATCH‘, ‘PUT‘, ‘DELETE‘]
當ITEM_METHODS 列表中的方法授權給項目端點(/people/)時RESOURCE_METHODS表中的方法才授權資源端點(/people)。都設定則會有一個全域範圍並使所有的端點都有效。然而你也可以啟用或者禁用單個端點的HTTP方法等級,我們很快就能看到。
由於我們允許了編輯了,我們也希望讓資料可以進行合適驗證。讓我們為people資源定義一種模式。
schema = { # Schema definition, based on Cerberus grammar. Check the Cerberus project # (https://github.com/nicolaiarocci/cerberus) for details. ‘firstname‘: { ‘type‘: ‘string‘, ‘minlength‘: 1, ‘maxlength‘: 10, }, ‘lastname‘: { ‘type‘: ‘string‘, ‘minlength‘: 1, ‘maxlength‘: 15, ‘required‘: True, # talk about hard constraints! For the purpose of the demo # ‘lastname‘ is an API entry-point, so we need it to be unique. ‘unique‘: True, }, # ‘role‘ is a list, and can only contain values from ‘allowed‘. ‘role‘: { ‘type‘: ‘list‘, ‘allowed‘: ["author", "contributor", "copy"], }, # An embedded ‘strongly-typed‘ dictionary. ‘location‘: { ‘type‘: ‘dict‘, ‘schema‘: { ‘address‘: {‘type‘: ‘string‘}, ‘city‘: {‘type‘: ‘string‘} }, }, ‘born‘: { ‘type‘: ‘datetime‘, },}
更多的資訊驗證請看 資料有效性。
現在讓我們討論下我們想進一步定製端點的people,我們想:
設定一項的標題為person
增加一個額外的自訂項端點在/people/
覆蓋預設緩衝控制指令
禁用people 端點的DELETE(設定全域變數)
這裡是完整得展示setting.py檔案更新中people的定義:
people = { # ‘title‘ tag used in item links. Defaults to the resource title minus # the final, plural ‘s‘ (works fine in most cases but not for ‘people‘) ‘item_title‘: ‘person‘, # by default the standard item entry point is defined as # ‘/people/<ObjectId>‘. We leave it untouched, and we also enable an # additional read-only entry point. This way consumers can also perform # GET requests at ‘/people/<lastname>‘. ‘additional_lookup‘: { ‘url‘: ‘regex("[\w]+")‘, ‘field‘: ‘lastname‘ }, # We choose to override global cache-control directives for this resource. ‘cache_control‘: ‘max-age=10,must-revalidate‘, ‘cache_expires‘: 10, # most global settings can be overridden at resource level ‘resource_methods‘: [‘GET‘, ‘POST‘], ‘schema‘: schema}
最後我們更新網域定義:
DOMAIN = { ‘people‘: people,}
儲存setting.py 和啟動 run.py。現在我們可以在people端點插入文檔了:
$ curl -d ‘[{"firstname": "barack", "lastname": "obama"}, {"firstname": "mitt", "lastname": "romney"}]‘ -H ‘Content-Type: application/json‘ http://127.0.0.1:5000/peopleHTTP/1.0 201 OK
我們也可以更新和刪除項目(但不能是整個資源,因為我們禁用了)。我們也可以執行GET請求擷取這個新的lastname端點:
$ curl -i http://127.0.0.1:5000/people/obamaHTTP/1.0 200 OKEtag: 28995829ee85d69c4c18d597a0f68ae606a266ccLast-Modified: Wed, 21 Nov 2012 16:04:56 GMTCache-Control: ‘max-age=10,must-revalidate‘Expires: 10...
{ "firstname": "barack", "lastname": "obama", "_id": "50acfba938345b0978fccad7" "updated": "Wed, 21 Nov 2012 16:04:56 GMT", "created": "Wed, 21 Nov 2012 16:04:56 GMT", "_links": { "self": {"href": "people/50acfba938345b0978fccad7", "title": "person"}, "parent": {"href": "/", "title": "home"}, "collection": {"href": "people", "title": "people"} }}
緩衝準則和項目標題符合我們新的設定。請看產品特性擷取特性完整列表和更多的使用樣本。
後記:
所有的例子和程式碼片段都來自Live demo,這是一個全功能的API,你可以使用到自己的實驗和生活執行個體或本地(你也可以使用執行個體應用來填充或重設資料庫)。
python RESTful API架構:Eve 快速入門