在Pyramid中利用Cornice可以很方便的基于HTTP Accept header不同构建不同格式的响应内容。
1. 安装Cornice
pip install Cornice
2. 安装Cornice之后,会在系统中增加一个名为cornice的template,在学习时可以使用它创建一个简单的项目框架。
pcreate -t cornice myapp
创建好的项目相比pyramid的项目简单,只有一个__init__.py,一个views.py
3. 在views.py中定义了一个简单的api例子
hello = Service(name='hello', path='/', description="Simplest app")
@hello.get()
def get_info(request):
"""Returns Hello in JSON."""
return {'Hello': 'World’}
在该例子中,定义了一个url为/的api,访问这个api链接,将返回一个application/json响应。
4. 在__init__.py中使用include包含了cornice包
from pyramid.config import Configurator
def main(global_config, **settings):
config = Configurator(settings=settings)
config.include("cornice")
config.scan("myapp.views")
return config.make_wsgi_app()
5. 运行该程序,查看结果
python setup.py develop
pserve --reload myapp.ini
我们通过curl访问该url:curl -D - http://0.0.0.0:6543,得到如下响应内容
HTTP/1.1 200 OK
Content-Length: 18
Content-Type: application/json; charset=UTF-8
Date: Mon, 18 Nov 2013 06:46:49 GMT
Server: waitress
{"Hello": "World"}
从Content-Type中可以看到,取得的内容为application/json格式
6. 构建一个文本格式返回结果
为了取得文本结果,我们需要将view的结果进行格式化,因此在__init__.py中加入如下renderer
class TextRenderer(object):
def __init__(self, info):
pass
def __call__(self, value, system):
request = system.get('request')
if request is not None:
response = request.response
response.content_type = 'text/plain'
name = value['Hello']
return u"Hello, {}!".format(name)
注:如果不需要进行类似上面的数据转化,可以直接使用string renderer。
然后,在main函数中加入config.add_renderer('text', TextRenderer)
7. 修改views.py 以接收不同的HTTP Header
@hello.get(accept='text/plain', renderer='text')
@hello.get(accept='application/json', renderer='json')
def get_info(request):
"""Returns Hello in JSON."""
return {'Hello': 'World'}
上面的两个@分别表示当get中的HTTP Header不同时的处理(使用不同的renderer对数据进行不同渲染)
8. 使用不同的HTTP Header查看结果
$ curl -D - -H 'Accept: text/plain' http://0.0.0.0:6543
HTTP/1.1 200 OK
Content-Length: 13
Content-Type: text/plain; charset=UTF-8
Date: Fri, 15 Nov 2013 11:22:41 GMT
Server: waitress
Hello, World!
$ curl -D - -H 'Accept: application/json' http://0.0.0.0:6543
HTTP/1.1 200 OK
Content-Length: 18
Content-Type: application/json; charset=UTF-8
Date: Fri, 15 Nov 2013 11:22:48 GMT
Server: waitress
{"Hello": "World"}
9. cornice与参数校验的整合
cornice可以很好的跟colander校验库结合使用。下面我们加入一个输入参数尝试一下。
9.1 安装colander
pip install colander
9.2 在views.py中增加一个校验规则
import colander
class NameSchema(colander.MappingSchema):
name = colander.SchemaNode(colander.String(),
validator=colander.Length(2))
该校验规则表示系统接收一个名为name的参数,且该参数为字符串类型,最小长度为2(Length参数为min,max,这里省略了max)
9.3 在views.py中增加参数处理方法
@hello.post(accept='text/plain', renderer='text', schema=NameSchema)
@hello.post(accept='application/json', renderer='json', schema=NameSchema)
def post_info(request):
"""Returns Hello in JSON."""
name = request.validated['name']
return {'Hello': name}
上面的方法为/这个url增加了post处理。
9.4 取得运行结果
curl -H 'Accept: application/json' http://0.0.0.0:6543 -d '{"name": "Alex"}'
结果:{"status": "error", "errors": [{"location": "body", "name": "name", "description": "name is missing"}]}
这是因为cornice默认接收的Content-Type是application/x-www-form-urlencoded,因此不能解析-d '{"name": "Alex"}' 这种参数
$ curl -H 'Accept: application/json' http://0.0.0.0:6543 -d 'name=Alex'
{"Hello": "Alex"}
$ curl -H 'Accept: application/json' -H 'Content-Type: application/json' http://0.0.0.0:6543 -d '{"name": "Alex"}'
{"Hello": "Alex"}
该例子中指定了Content-Type,因此系统能识别-d '{"name": "Alex"}'
$ curl -H 'Accept: application/json' -H 'Content-Type: application/json' http://0.0.0.0:6543 -d '{"name": "A"}'
{"status": "error", "errors": [{"location": "body", "name": "name", "description": "Shorter than minimum length 2"}]}
本文是http://makina-corpus.com/blog/metier/multi-format-restful-api-with-cornice的一个摘要翻译,需要查看原文请自行前往。
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment