用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的Django框架中的数据库配置指南
Jul 17 Python
python虚拟环境virtualenv的安装与使用
Sep 21 Python
python 读入多行数据的实例
Apr 19 Python
python 正确保留多位小数的实例
Jul 16 Python
深入浅析Python2.x和3.x版本的主要区别
Nov 30 Python
Python可视化mhd格式和raw格式的医学图像并保存的方法
Jan 24 Python
Python分布式进程中你会遇到的问题解析
May 28 Python
Python Django Vue 项目创建过程详解
Jul 29 Python
python树的同构学习笔记
Sep 14 Python
Pycharm和Idea支持的vim插件的方法
Feb 21 Python
python入门教程之基本算术运算符
Nov 13 Python
深入理解python多线程编程
Apr 18 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
PHP 数据结构队列(SplQueue)和优先队列(SplPriorityQueue)简单使用实例
2015/05/12 PHP
深入浅析php json 格式控制
2015/12/24 PHP
php fread函数使用方法总结
2019/05/28 PHP
Javascript开发包大全整理
2006/12/22 Javascript
javascript KeyDown、KeyPress和KeyUp事件的区别与联系
2009/12/03 Javascript
javascript采用数组实现tab菜单切换效果
2012/12/12 Javascript
AngularJS表单编辑提交功能实例
2015/02/13 Javascript
js实现跨域的方法实例详解
2015/06/24 Javascript
js实现字符串和数组之间相互转换操作
2016/01/12 Javascript
Javascript中prototype的使用详解
2016/06/18 Javascript
如何在JS中实现相互转换XML和JSON
2016/07/19 Javascript
JS获取鼠标选中的文字
2016/08/10 Javascript
JS实现的RGB网页颜色在线取色器完整实例
2016/12/21 Javascript
JS正则表达式修饰符中multiline(/m)用法分析
2016/12/27 Javascript
JavaScript代码判断输入的字符串是否含有特殊字符和表情代码实例
2017/08/17 Javascript
jQuery实现条件搜索查询、实时取值及升降序排序的方法分析
2019/05/04 jQuery
解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
2020/04/21 Javascript
基于小程序请求接口wx.request封装的类axios请求
2020/07/02 Javascript
解决父组件将子组件作为弹窗调用只执行一次created的问题
2020/07/24 Javascript
[46:43]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#2LGD VS MVP.Phx第二局
2016/03/02 DOTA
巧用Python装饰器 免去调用父类构造函数的麻烦
2012/05/18 Python
Python多线程编程(二):启动线程的两种方法
2015/04/05 Python
Python通过select实现异步IO的方法
2015/06/04 Python
使用Python绘制图表大全总结
2017/02/11 Python
怎么使用pipenv管理你的python项目
2018/03/12 Python
基于DOM+CSS3实现OrgChart组织结构图插件
2016/03/02 HTML / CSS
prAna官网:瑜伽、旅行和冒险服装
2019/03/10 全球购物
一套SQL笔试题
2016/08/14 面试题
大学生标准推荐信范文
2013/11/25 职场文书
关于礼仪的演讲稿
2014/01/04 职场文书
建筑设计专业求职自我评价
2014/03/02 职场文书
银行委托书范本
2014/04/04 职场文书
超市开店计划书
2014/09/15 职场文书
人事主管岗位职责
2015/02/04 职场文书
2015年中秋晚会主持稿
2015/07/30 职场文书
浅析CSS在DevTools 中架构演变
2021/10/05 HTML / CSS