用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 time模块详解(常用函数实例讲解,非常好)
Apr 24 Python
零基础写python爬虫之HTTP异常处理
Nov 05 Python
python输出指定月份日历的方法
Apr 23 Python
Python编码类型转换方法详解
Jul 01 Python
解决PySide+Python子线程更新UI线程的问题
Jan 11 Python
Python实现操纵控制windows注册表的方法分析
May 24 Python
Python scipy的二维图像卷积运算与图像模糊处理操作示例
Sep 06 Python
浅谈pytorch卷积核大小的设置对全连接神经元的影响
Jan 10 Python
Pyqt5 关于流式布局和滚动条的综合使用示例代码
Mar 24 Python
jupyter notebook 的工作空间设置操作
Apr 20 Python
python 实现简易的记事本
Nov 30 Python
Selenium Webdriver元素定位的八种常用方式(小结)
Jan 13 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
利用中国天气预报接口实现简单天气预报
2014/01/20 PHP
PHP保存带BOM文件的方法
2015/02/12 PHP
thinkPHP中钩子的使用方法实例分析
2017/11/16 PHP
JS分页效果示例
2013/10/11 Javascript
一个简单的Node.js异步操作管理器分享
2014/04/29 Javascript
javascript常见操作汇总
2014/09/03 Javascript
JavaScript实现向OL列表内动态添加LI元素的方法
2015/03/21 Javascript
JS触发服务器控件的单击事件(详解)
2016/08/06 Javascript
Ztree新增角色和编辑角色回显问题的解决
2016/10/25 Javascript
详解JavaScript跨域总结与解决办法
2016/10/31 Javascript
Node.js测试中的Mock文件系统详解
2016/11/21 Javascript
AngularJS改变元素显示状态
2017/04/20 Javascript
swiper插件自定义切换箭头按钮
2017/12/28 Javascript
使用vue2.6实现抖音【时间轮盘】屏保效果附源码
2019/04/24 Javascript
vue-router跳转时打开新页面的两种方法
2019/07/29 Javascript
Vue中axios的封装(报错、鉴权、跳转、拦截、提示)
2019/08/20 Javascript
vue.js的简单自动求和计算实例
2019/11/08 Javascript
javascript设计模式 ? 单例模式原理与应用实例分析
2020/04/09 Javascript
Vue触发input选取文件点击事件操作
2020/08/07 Javascript
python发送邮件接收邮件示例分享
2014/01/21 Python
python操作xml文件详细介绍
2014/06/09 Python
Python for循环生成列表的实例
2018/06/15 Python
10分钟用python搭建一个超好用的CMDB系统
2019/07/17 Python
Python之Numpy的超实用基础详细教程
2019/10/23 Python
python取均匀不重复的随机数方式
2019/11/27 Python
基于python求两个列表的并集.交集.差集
2020/02/10 Python
150行python代码实现贪吃蛇游戏
2020/04/24 Python
英国儿童鞋和靴子:Start-Rite
2019/05/06 全球购物
BAILEY 44官网:美国制造的女性服装
2019/07/01 全球购物
启动一个线程是用run()还是start()
2016/12/25 面试题
阳光体育活动实施方案
2014/05/25 职场文书
2014年餐厅服务员工作总结
2014/11/18 职场文书
监考失职检讨书
2015/01/26 职场文书
家长会后的感想
2015/08/11 职场文书
深入解读Java三大集合之map list set的用法
2021/11/11 Java/Android
Echarts如何重新渲染实例详解
2022/05/30 Javascript