快速启动¶
渴望开始?本页首先介绍了EVE。
先决条件¶
最小应用程序¶
最小的EVE应用程序如下所示:
from eve import Eve
app = Eve()
if __name__ == '__main__':
app.run()
只需将其保存为run.py。接下来,创建一个包含以下内容的新文本文件:
DOMAIN = {'people': {}}
将其另存为与run.py存储在同一目录中的settings.py。这是一个标准的python模块eve配置文件,它告诉eve您的API只包含一个可访问的资源, people
.
现在您已经准备好启动API了。
$ python run.py
* Running on http://127.0.0.1:5000/
现在您可以使用API:
$ curl -i http://127.0.0.1:5000
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 82
Server: Eve/0.0.5-dev Werkzeug/0.8.3 Python/2.7.3
Date: Wed, 27 Mar 2013 16:06:44 GMT
恭喜,您的GET请求得到了很好的回复。让我们看看有效载荷:
{
"_links": {
"child": [
{
"href": "people",
"title": "people"
}
]
}
}
API入口点遵循 HATEOAS 原理并提供有关可通过API访问的资源的信息。在我们的例子中,只有一个可用的子资源,即 people
.
尝试请求 people
现在:
$ curl http://127.0.0.1:5000/people
{
"_items": [],
"_links": {
"self": {
"href": "people",
"title": "people"
},
"parent": {
"href": "/",
"title": "home"
}
},
"_meta": {
"max_results": 25,
"page": 1,
"total": 0
}
}
这一次我们也得到了一个 _items
单子。这个 _links
是相对于被访问的资源的,因此您可以获得指向父资源(主页)和资源本身的链接。如果从pymongo收到超时错误,请确保满足前提条件。可能的情况是, mongod
服务器进程未运行。
默认情况下,EVE API是只读的:
$ 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用户失望。
数据库插曲¶
让我们通过将以下行添加到settings.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 = 27017
# Skip this block if your db has no auth. But it really should.
MONGO_USERNAME = '<your username>'
MONGO_PASSWORD = '<your password>'
# Name of the database on which the user can be authenticated,
# needed if --auth mode is enabled.
MONGO_AUTH_SOURCE = '<dbname>'
MONGO_DBNAME = 'apitest'
由于MongoDB 懒惰 我们不需要创建数据库集合。实际上,我们甚至不需要创建数据库:在空的/不存在的数据库上的GET请求将得到正确的服务。 (200 OK
集合为空);删除/修补/放置将收到相应的响应 (404 Not Found
)和post请求将根据需要创建数据库和集合。然而,这样一个自动管理的数据库由于缺乏索引和任何类型的优化而性能非常差。
更复杂的应用程序¶
到目前为止,我们的API是只读的。让我们启用全谱的CRUD操作:
# 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']
RESOURCE_METHODS
列出资源终结点允许的方法 (/people
)当 ITEM_METHODS
列出在项终结点启用的方法 (/people/<ObjectId>
)。这两个设置都有一个全局范围,并将应用于所有终结点。然后,您可以在各个端点级别启用或禁用HTTP方法,我们将很快看到这一点。
因为我们正在启用编辑,所以我们还希望启用适当的数据验证。让我们为我们的 people
资源。
schema = {
# Schema definition, based on Cerberus grammar. Check the Cerberus project
# (https://github.com/pyeve/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
添加额外的 custom item endpoint 在
/people/<lastname>
覆盖默认值 cache control directives
禁用删除
/people
端点(我们全局启用)
以下是如何完成 people
定义在更新的settings.py文件中查找:
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,
}
保存settings.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/people
HTTP/1.0 201 OK
我们还可以更新和删除项目(但不是整个资源,因为我们禁用了它)。我们还可以对新的 lastname
终结点:
$ curl -i http://127.0.0.1:5000/people/obama
HTTP/1.0 200 OK
Etag: 28995829ee85d69c4c18d597a0f68ae606a266cc
Last-Modified: Wed, 21 Nov 2012 16:04:56 GMT
Cache-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"}
}
}
缓存指令和项标题与我们的新设置匹配。参见 特征 有关可用功能和更多用法示例的完整列表。