用Python编写web API的教程


Posted in Python onApril 30, 2015

自从Roy Fielding博士在2000年他的博士论文中提出REST(Representational State Transfer)风格的软件架构模式后,REST就基本上迅速取代了复杂而笨重的SOAP,成为Web API的标准了。

什么是Web API呢?

如果我们想要获取一篇Blog,输入http://localhost:9000/blog/123,就可以看到id为123的Blog页面,但这个结果是HTML页面,它同时混合包含了Blog的数据和Blog的展示两个部分。对于用户来说,阅读起来没有问题,但是,如果机器读取,就很难从HTML中解析出Blog的数据。

如果一个URL返回的不是HTML,而是机器能直接解析的数据,这个URL就可以看成是一个Web API。比如,读取http://localhost:9000/api/blogs/123,如果能直接返回Blog的数据,那么机器就可以直接读取。

REST就是一种设计API的模式。最常用的数据格式是JSON。由于JSON能直接被JavaScript读取,所以,以JSON格式编写的REST风格的API具有简单、易读、易用的特点。

编写API有什么好处呢?由于API就是把Web App的功能全部封装了,所以,通过API操作数据,可以极大地把前端和后端的代码隔离,使得后端代码易于测试,前端代码编写更简单。

一个API也是一个URL的处理函数,我们希望能直接通过一个@api来把函数变成JSON格式的REST API,这样,获取注册用户可以用一个API实现如下:

@api
@get('/api/users')
def api_get_users():
  users = User.find_by('order by created_at desc')
  # 把用户的口令隐藏掉:
  for u in users:
    u.password = '******'
  return dict(users=users)

所以,@api这个decorator只要编写好了,就可以把任意的URL处理函数变成API调用。

新建一个apis.py,编写@api负责把函数的返回结果序列化为JSON:

def api(func):
  @functools.wraps(func)
  def _wrapper(*args, **kw):
    try:
      r = json.dumps(func(*args, **kw))
    except APIError, e:
      r = json.dumps(dict(error=e.error, data=e.data, message=e.message))
    except Exception, e:
      r = json.dumps(dict(error='internalerror', data=e.__class__.__name__, message=e.message))
    ctx.response.content_type = 'application/json'
    return r
  return _wrapper

@api需要对Error进行处理。我们定义一个APIError,这种Error是指API调用时发生了逻辑错误(比如用户不存在),其他的Error视为Bug,返回的错误代码为internalerror。

客户端调用API时,必须通过错误代码来区分API调用是否成功。错误代码是用来告诉调用者出错的原因。很多API用一个整数表示错误码,这种方式很难维护错误码,客户端拿到错误码还需要查表得知错误信息。更好的方式是用字符串表示错误代码,不需要看文档也能猜到错误原因。

可以在浏览器直接测试API,例如,输入http://localhost:9000/api/users,就可以看到返回的JSON:

Python 相关文章推荐
python编码最佳实践之总结
Feb 14 Python
详解Python import方法引入模块的实例
Aug 02 Python
numpy使用技巧之数组过滤实例代码
Feb 03 Python
使用Python实现在Windows下安装Django
Oct 17 Python
Python读取mat文件,并保存为pickle格式的方法
Oct 23 Python
python调用opencv实现猫脸检测功能
Jan 15 Python
Python OpenCV利用笔记本摄像头实现人脸检测
Aug 20 Python
Python操作redis实例小结【String、Hash、List、Set等】
May 16 Python
python实现XML解析的方法解析
Nov 16 Python
Python中url标签使用知识点总结
Jan 16 Python
django template实现定义临时变量,自定义赋值、自增实例
Jul 12 Python
基于Django集成CAS实现流程详解
Nov 28 Python
为Python的web框架编写前端模版的教程
Apr 30 #Python
为Python的web框架编写MVC配置来使其运行的教程
Apr 30 #Python
在Python的web框架中配置app的教程
Apr 30 #Python
python实现从ftp服务器下载文件的方法
Apr 30 #Python
简单介绍Python下自己编写web框架的一些要点
Apr 29 #Python
编写Python的web框架中的Model的教程
Apr 29 #Python
python获取本地计算机名字的方法
Apr 29 #Python
You might like
GD输出汉字的函数的分析
2006/10/09 PHP
ThinkPHP验证码和分页实例教程
2014/08/22 PHP
iOS自定义提示弹出框实现类似UIAlertView的效果
2016/11/16 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
PHP strripos函数用法总结
2019/02/11 PHP
setTimeout和setInterval的浏览器兼容性分析
2007/02/27 Javascript
javascript window对象属性整理
2009/10/24 Javascript
js DataSet数据源处理代码
2010/03/29 Javascript
js实现网页倒计时、网站已运行时间功能的代码3例
2014/04/14 Javascript
jquery中获得元素尺寸和坐标的方法整理
2014/05/18 Javascript
nodejs npm包管理的配置方法及常用命令介绍
2014/06/05 NodeJs
基于Bootstrap重置输入框内容按钮插件
2016/05/12 Javascript
JQuery异步加载PartialView的方法
2016/06/07 Javascript
基于JavaScript实现轮播图代码
2016/07/14 Javascript
JS实现字符串转驼峰格式的方法
2016/12/16 Javascript
VUE中v-model和v-for指令详解
2017/06/23 Javascript
Express本地测试HTTPS的示例代码
2018/06/06 Javascript
JS实现图片上传多次上传同一张不生效的处理方法
2018/08/06 Javascript
springMvc 前端用json的方式向后台传递对象数组方法
2018/08/07 Javascript
微信小程序实现页面下拉刷新和上拉加载功能详解
2018/12/03 Javascript
解决在layer.open中使用时间控件laydate失败的问题
2019/09/11 Javascript
使用axios发送post请求,将JSON数据改为form类型的示例
2019/10/31 Javascript
javascript中的with语句学习笔记及用法
2020/02/17 Javascript
详解JavaScript匿名函数和闭包
2020/07/10 Javascript
[02:53]DOTA2英雄基础教程 山岭巨人小小
2013/12/09 DOTA
[03:47]2015国际邀请赛第三日现场精彩回顾
2015/08/08 DOTA
Python中用于检查英文字母大写的isupper()方法
2015/05/19 Python
python中MethodType方法介绍与使用示例
2017/08/03 Python
python标准库sys和OS的函数使用方法与实例详解
2020/02/12 Python
python之MSE、MAE、RMSE的使用
2020/02/24 Python
IntelliJ 中配置 Anaconda的过程图解
2020/06/01 Python
Keras设置以及获取权重的实现
2020/06/19 Python
美国购买肉、鸭、家禽、鹅肝和熟食网站:D’Artagnan
2018/11/13 全球购物
小学班主任经验交流材料
2014/12/16 职场文书
检讨书怎么写
2015/01/23 职场文书
Nginx服务器添加Systemd自定义服务过程解析
2021/03/31 Servers