是时候编写你第一个 REST API。本指南假设你对 Flask 有必定的认识,而且已经安装了 Flask 和 Flask-RESTful。python
一个最小的 Flask-RESTful API 像这样:flask
from flask import Flask from flask_restful import Api, Resource app = Flask(__name__) api = Api(app) class HelloWorld(Resource): def get(self): return {'hello': 'world'} api.add_resource(HelloWorld, '/') if __name__ == '__main__': app.run(debug=True)
Flask-RESTful 提供的最主要的基础就是资源(resources)。api
资源(Resources)是构建在 Flask 可拔插视图 之上,只要在你的资源(resource)上定义方法就可以容易地访问多个 HTTP 方法。restful
一个待办事项应用程序的基本的 CRUD 资源看起来像这样:数据结构
todos = {} class TodoSimple(Resource): def get(self, todo_id): return {todo_id: todos[todo_id]} def put(self, todo_id): todos[todo_id] = request.form['data'] return {todo_id: todos[todo_id]} api.add_resource(TodoSimple, '/<string:todo_id>')
Flask-RESTful 支持视图方法多种类型的返回值。同 Flask 同样,你能够返回任一迭代器,它将会被转换成一个包含原始 Flask 响应对象的响应。app
Flask-RESTful 也支持使用多个返回值来设置响应代码和响应头,以下所示:ide
class Todo1(Resource): def get(self): # Default to 200 OK return {'task': 'Hello world'} class Todo2(Resource): def get(self): # Set the response code to 201 return {'task': 'Hello world'}, 201 class Todo3(Resource): def get(self): # Set the response code to 201 and return custom headers return {'task': 'Hello world'}, 201, {'Etag': 'some-opaque-string'}
不少时候在一个 API 中,你的资源能够经过多个 URLs 访问。你能够把多个 URLs 传给 Api 对象的 Api.add_resource() 方法。每个 URL 都能访问到你的 Resource。函数
api.add_resource(HelloWorld, '/', '/hello')
你也能够为你的资源方法指定 endpoint 参数。this
api.add_resource(Todo, '/todo/<int:todo_id>', endpoint='todo_ep')
尽管 Flask 可以简单地访问请求数据(好比查询字符串或者 POST 表单编码的数据),验证表单数据仍然很痛苦。编码
Flask-RESTful 内置了支持验证请求数据,它使用了一个相似 argparse 的库。
parser = reqparse.RequestParser() parser.add_argument('rate', type=int, help='Rate to charge for this resource') args = parser.parse_args()
须要注意地是与 argparse 模块不一样,reqparse.RequestParser.parse_args() 返回一个 Python 字典而不是一个自定义的数据结构。
使用 reqparse 模块一样能够自由地提供聪明的错误信息。若是参数没有经过验证,Flask-RESTful 将会以一个 400 错误请求以及高亮的错误信息回应。
inputs 模块提供了许多的常见的转换函数,好比 inputs.date() 和 inputs.url()。
使用 strict=True 调用 parse_args 可以确保当请求包含你的解析器中未定义的参数的时候会抛出一个异常。
args = parser.parse_args(strict=True)
默认状况下,在你的返回迭代中全部字段将会原样呈现。
尽管当你刚刚处理 Python 数据结构的时候,以为这是一个伟大的工做,可是当实际处理它们的时候,会以为十分沮丧和枯燥。
为了解决这个问题,Flask-RESTful 提供了 fields 模块和 marshal_with() 装饰器。
相似 Django ORM 和 WTForm,你可使用 fields 模块来在你的响应中格式化结构。
from collections import OrderedDict from flask.ext.restful import fields, marshal_with resource_fields = { 'task': fields.String, 'uri': fields.Url('todo_ep') } class TodoDao(object): def __init__(self, todo_id, task): self.todo_id = todo_id self.task = task # This field will not be sent in the response self.status = 'active' class Todo(Resource): @marshal_with(resource_fields) def get(self, **kwargs): return TodoDao(todo_id='my_todo', task='Remember the milk')
上面的例子接受一个 python 对象并准备将其序列化。marshal_with() 装饰器将会应用到由 resource_fields 描述的转换。
从对象中提取的惟一字段是 task。
fields.Url 域是一个特殊的域,它接受端点(endpoint)名称做为参数而且在响应中为该端点生成一个 URL。
许多你须要的字段类型都已经包含在内。