用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中的__slots__使用示例
Feb 26 Python
浅析Python中的多进程与多线程的使用
Apr 07 Python
python制作小说爬虫实录
Aug 14 Python
Python中format()格式输出全解
Apr 12 Python
python3中property使用方法详解
Apr 23 Python
Python Django Cookie 简单用法解析
Aug 13 Python
Python爬虫实现使用beautifulSoup4爬取名言网功能案例
Sep 15 Python
使用Python画出小人发射爱心的代码
Nov 23 Python
python词云库wordcloud的使用方法与实例详解
Feb 17 Python
Python异常继承关系和自定义异常实现代码实例
Feb 20 Python
python右对齐的实例方法
Jul 05 Python
python 视频下载神器(you-get)的具体使用
Jan 06 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
星际争霸教主Flash的ID由来:你永远不会知道他之前的ID是www!
2019/01/18 星际争霸
PHP自带函数给数字或字符串自动补齐位数
2014/07/29 PHP
CI框架入门之MVC简单示例
2016/11/21 PHP
PHP/ThinkPHP实现批量打包下载文件的方法示例
2017/07/31 PHP
javascript eval函数深入认识
2009/02/21 Javascript
JQuery读取XML文件数据并显示的实现代码
2009/12/16 Javascript
ExtJS 2.0 GridPanel基本表格简明教程
2010/05/25 Javascript
Asp.Net alert弹出提示信息的几种方法总结
2014/01/29 Javascript
JS实现网页滚动条感应鼠标变色的方法
2015/02/26 Javascript
JavaScript弹出新窗口并控制窗口移动到指定位置的方法
2015/04/06 Javascript
jQuery获取checkbox选中的值
2016/01/28 Javascript
JavaScript中子对象访问父对象的方式详解
2016/09/01 Javascript
jQuery表单对象属性过滤选择器实例详解
2016/09/13 Javascript
JS实现微信弹出搜索框 多条件查询功能
2016/12/13 Javascript
详解angularJs中自定义directive的数据交互
2017/01/13 Javascript
JavaScript数据结构之二叉树的计数算法示例
2017/04/13 Javascript
详解Vue路由开启keep-alive时的注意点
2017/06/20 Javascript
jquery实现一个全局计时器(商城可用)
2017/06/30 jQuery
微信小程序 冒泡事件原理解析
2019/09/27 Javascript
VUE+elementui面包屑实现动态路由详解
2019/11/04 Javascript
vue.js的状态管理vuex中store的使用详解
2019/11/08 Javascript
微信小程序实现拨打电话功能的示例代码
2020/06/28 Javascript
python数据结构之二叉树的遍历实例
2014/04/29 Python
使用Python脚本将Bing的每日图片作为桌面的教程
2015/05/04 Python
举例讲解Python中metaclass元类的创建与使用
2016/06/30 Python
python 简单的绘图工具turtle使用详解
2017/06/21 Python
Python AES加密实例解析
2018/01/18 Python
解决TensorFlow调用Keras库函数存在的问题
2020/07/06 Python
Python执行时间的几种计算方法
2020/07/31 Python
英国独特家具和家庭用品购物网站:Cuckooland
2020/08/30 全球购物
影视制作岗位职责
2013/12/04 职场文书
工程招投标邀请书
2014/01/26 职场文书
《赵州桥》教学反思
2014/02/17 职场文书
事务机电主管工作职责
2014/02/25 职场文书
股东合作协议书模板2篇
2019/11/05 职场文书
手把手教你从零开始react+antd搭建项目
2021/06/03 Javascript