用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 动态获取当前运行的类名和函数名的方法
Apr 15 Python
Python中asyncore的用法实例
Sep 29 Python
Python中字符串对齐方法介绍
May 21 Python
在主机商的共享服务器上部署Django站点的方法
Jul 22 Python
Python中MySQLdb和torndb模块对MySQL的断连问题处理
Nov 09 Python
Python操作使用MySQL数据库的实例代码
May 25 Python
python装饰器实例大详解
Oct 25 Python
详解Python3中setuptools、Pip安装教程
Jun 18 Python
python字符串Intern机制详解
Jul 01 Python
Python3如何在Windows和Linux上打包
Feb 25 Python
解决django的template中如果无法引用MEDIA_URL问题
Apr 07 Python
Python 实现一行输入多个数字(用空格隔开)
Apr 29 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 Image Resize图片大小调整的函数代码
2011/01/17 PHP
PHP中使用匿名函数操作数据库的例子
2014/11/17 PHP
简单介绍PHP的责任链编程模式
2015/08/11 PHP
php实现Mysql简易操作类
2015/10/11 PHP
php+redis实现商城秒杀功能
2020/11/19 PHP
javascript 运算数的求值顺序
2011/08/23 Javascript
JavaScript中对循环语句的优化技巧深入探讨
2014/06/06 Javascript
node.js实现逐行读取文件内容的代码
2014/06/27 Javascript
AngularJS的内置过滤器详解
2015/05/14 Javascript
jquery实现仿JqueryUi可拖动的DIV实例
2015/07/31 Javascript
js HTML5上传示例代码完整版
2016/10/10 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
2016/11/07 Javascript
jQuery实现动态生成表格并为行绑定单击变色动作的方法
2017/04/17 jQuery
详解基于Vue+Koa的pm2配置
2017/10/24 Javascript
解决webpack dev-server不能匹配post请求的问题
2018/08/24 Javascript
引入外部js脚本加载慢与页面白屏问题的解决
2018/12/10 Javascript
elementUI select组件默认选中效果实现的方法
2019/03/25 Javascript
微信小程序 wxParse插件显示视频问题
2019/09/27 Javascript
使用React代码动态生成栅格布局的方法
2020/05/24 Javascript
Antd的table组件表格的序号自增操作
2020/10/27 Javascript
零基础写python爬虫之使用Scrapy框架编写爬虫
2014/11/07 Python
Python实现批量下载图片的方法
2015/07/08 Python
python+Splinter实现12306抢票功能
2018/09/25 Python
Python基于datetime或time模块分别获取当前时间戳的方法实例
2019/02/19 Python
浅谈Python小波分析库Pywavelets的一点使用心得
2019/07/09 Python
为什么从Python 3.6开始字典有序并效率更高
2019/07/15 Python
阿根廷网上配眼镜:SmartBuyGlasses阿根廷
2016/08/19 全球购物
六道php面试题附答案
2014/06/05 面试题
酒店个人培训自我鉴定
2013/12/11 职场文书
求职毕业生自荐书
2014/02/08 职场文书
和睦家庭事迹
2014/05/14 职场文书
警察群众路线对照检查材料思想汇报
2014/10/01 职场文书
个人廉政承诺书
2015/04/28 职场文书
python编写五子棋游戏
2021/05/25 Python
图文详解Nginx版本平滑升级方案
2021/09/15 Servers
2022新作动画《福星小子》释出宣传影片 加入内田真礼&宫野真守配音演出
2022/04/08 日漫