REST REST是所有Web应用都应该遵守的架构设计指导原则,Representational State Transfer(表现层状态转化),面向资源是REST最明显的特征,对于同一资源的一组不同的操作,资源是服务器上一个可命名的抽象概念,资源是以名词为核心来组织的,首先关注的是名词。REST要求,必须通过统一接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。
安装和使用 1 pip install flask-restful
1 from flask import Flask2 from flask.ext import restful3 4 app=Flask(__name__) 5 api=restful.Api(app) 6 7 class HelloFlask (restful.Resource) :8 def get (self) : 9 return {'hello' :'flask' } 10 11 api.add_resource(HelloFlask,'/' ) 12 13 if __name__ == "__main__" :14 app.run(debug=True )
Flask-RESTful提供的最主要的基础就是resources,只要在你的资源上定义方法就能容易地访问多个HTTP方法。
1 from flask import Flask,request2 from flask.ext.restful import Resource,Api3 4 app=Flask(__name__) 5 api=Api(app) 6 7 todos={} 8 9 class TodoSimple (Resource) :10 def get (self,todo_id) : 11 return {todo_id:todos[todo_id]} 12 def put (self,todo_id) : 13 todos[todo_id]=request.form['data' ] 14 return {todo_id:todos[todo_id]} 15 16 api.add_resource(TodoSimple,'/<string:todo_id>' ) 17 18 if __name__ == "__main__" :19 app.run(debug=True )
1 ~] 2 { 3 "todo1" : "Change Me" 4 } 5 ~] 6 { 7 "todo1" : "Change Me" 8 }
1 >>> from requests import put,get2 >>> put('http://127.0.0.1:5000/todo2' ,data={'data' :"Remember Me" }).json()3 {'todo2' : 'Remember Me' } 4 >>> get('http://127.0.0.1:5000/todo2' ).json()5 {'todo2' : 'Remember Me' }
Flask-RESTful支持视图方法多种类型返回值,它将会被转换成一个包含原始 Flask 响应对象的响应,Flask-RESTful 也支持使用多个返回值来设置响应代码和响应头。
1 from flask import Flask2 from flask.ext.restful import Resource,Api3 4 app=Flask(__name__) 5 api=Api(app) 6 7 class Default (Resource) :8 def get (self) : 9 return {'message' :'OK' } 10 class Error (Resource) :11 def get (self) : 12 return {'error' :'fail' },404 13 class Header (Resource) :14 def get (self) : 15 return {'api' :'Restful' },201 ,{'Server' :'Api Server' } 16 17 api.add_resource(Default,'/' ) 18 api.add_resource(Error,'/error' ) 19 api.add_resource(Header,'/header' ) 20 21 if __name__ == "__main__" :22 app.run(debug=True )
参数解析 Flask能够简单地访问请求数据(比如查询字符串或者POST表单编码的数据),验证表单数据仍然很痛苦,Flask-RESTful内置了支持验证请求数据,它使用了一个类似argparse的库。
1 from flask import Flask,request2 from flask.ext.restful import Resource,Api,reqparse3 4 app=Flask(__name__) 5 api=Api(app) 6 7 8 class Default (Resource) :9 def get (self,arg) : 10 return {arg:bands[arg]} 11 def put (self,arg) : 12 parser=reqparse.RequestParser() 13 parser.add_argument('rate' ,type=int,help='Rate must int' ) 14 args=parser.parse_args() 15 return args 16 api.add_resource(Default,'/<string:arg>' ) 17 18 if __name__ == "__main__" :19 app.run(debug=True )
1 ~] 2 { 3 "message" : { 4 "rate" : "rate must int" 5 } 6 } 7 ~] 8 { 9 "rate" : "1000" 10 }
完整例子:
1 from flask import Flask2 from flask.ext.restful import reqparse,abort,Api,Resource3 4 app=Flask(__name__) 5 api=Api(app) 6 7 TODOS={ 8 'todo1' :{'task' :'build an API' }, 9 'todo2' :{'task' :'????' }, 10 'todo3' :{'task' :'profit!' }, 11 } 12 13 def abort_if_todo_doesnt_exist (todo_id) :14 if todo_id not in TODOS: 15 abort(404 ,message="Todo {} doesn't exist" .format(todo_id)) 16 17 parser=reqparse.RequestParser() 18 parser.add_argument('task' ,type=str) 19 20 class Todo (Resource) :21 def get (self,todo_id) : 22 abort_if_todo_doesnt_exist(todo_id) 23 return TODOS[todo_id] 24 def delete (self,todo_id) : 25 abort_if_todo_doesnt_exist(todo_id) 26 del TODOS[todo_id] 27 return '' ,204 28 def put (self,todo_id) : 29 args=parser.parse_args() 30 task={'task' :args['task' ]} 31 TODOS[todo_id]=task 32 return task,201 33 class TodoList (Resource) :34 def get (self) : 35 return TODOS 36 37 def post (self) : 38 args=parser.parse_args() 39 todo_id=int(max(TODOS.keys()).lstrip('todo' ))+1 40 todo_id='todo%i' % todo_id 41 TODOS[todo_id]={'task' :args['task' ]} 42 return TODOS[todo_id],201 43 44 api.add_resource(TodoList,'/todos' ) 45 api.add_resource(Todo,'/todos/<todo_id>' ) 46 47 if __name__ == "__main__" :48 app.run()