用python写通用restful api service
Posted zhoutk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用python写通用restful api service相关的知识,希望对你有一定的参考价值。
一直在用node.js做后端,要逐步涉猎大数据范围,注定绕不过python,因此决定把一些成熟的东西用python来重写,一是开拓思路、通过比较来深入学习python;二是有目标,有动力,希望能持之以恒的坚持下去。
项目介绍
用python语言来写一个restful api service,数据库使用mysql。因为只做后端微服务,并且ORM的实现方式,采用自动生成SQL的方式来完成,因此选择了轻量级的flask作为web框架。如此选择,主要目的是针对中小规模的网络应用,能充分利用关系数据库的种种优势,来实现丰富的现代互联网应用。
restful api
restful api 的概念就不介绍了。这里说一下我们实现协议形式:
[GET]/rs/user/{id}/key1/value1/key2/value2/.../keyn/valuen
[POST]/rs/user[/{id}]
[PUT]/rs/user/{id}
[DELETE]/rs/user/{id}/key1/value1/key2/value2/.../keyn/valuen
说明:
- rs为资源标识;
- 第二节,user,会被解析为数据库表名;
- 查询时,id为空或0时,id会被忽略,即为列表查询;
- 新建和修改,除接收form表单外,url中的id参数也会被合并到参数集合中;
- 删除同查询。
让flask支持正则表达式
flask默认路由不支持正则表达式,而我需要截取完整的URL自己来解析,经查询,按以下步骤很容易完成任务。
- 使用werkzeug库 :from werkzeug.routing import BaseConverter
- 定义转换器:
class RegexConverter(BaseConverter):
def __init__(self, map, *args):
self.map = map
self.regex = args[0]
- 注册转换器 : app.url_map.converters[\'regex\'] = RegexConverter
- 用正则来截取url : @app.route(\'/rs/<regex(".*"):query_url>\', methods=[\'PUT\', \'DELETE\', \'POST\', \'GET\'])
几点疑问:
- 正则(.*)理论上应该是匹配任何除回车的所有字符,但不知道为什么,在这里不识别问号(?)
- 我用request.data来取表单数据,为何request.form取不到?
- \'/rs/<regex("."):query_url>\'后若加个反斜杠(\'/rs/<regex("."):query_url>/\'),request.data就取不到数据,为什么?
解析json数据
解析json数据很容易,但我需要对客户端送上来的数据进行校验,下面是用异常处理又只解析一次的解决方案。
def check_json_format(raw_msg):
try:
js = json.loads(raw_msg, encoding=\'utf-8\')
except ValueError:
return False, {}
return True, js
URL解析
按既定协议解析URL,提取表名,为生成sql组合参数集合。
@app.route(\'/rs/<regex(".*"):query_url>\', methods=[\'PUT\', \'DELETE\', \'POST\', \'GET\'])
def rs(query_url):
(flag, params) = check_json_format(request.data)
urls = query_url.split(\'/\')
url_len = len(urls)
if url_len < 1 or url_len > 2 and url_len % 2 == 1:
return "The params is wrong."
ps = {}
for i, al in enumerate(urls):
if i == 0:
table = al
elif i == 1:
idd = al
elif i > 1 and i % 2 == 0:
tmp = al
else:
ps[tmp] = al
ps[\'table\'] = table
if url_len > 1:
ps[\'id\'] = idd
if request.method == \'POST\' or request.method == \'PUT\':
params = dict(params, **{\'table\': ps.get(\'table\'), \'id\': ps.get(\'id\')})
if request.method == \'GET\' or request.method == \'DELETE\':
params = ps
return jsonify(params)
pycharm项目配置
配置好Run/Debug Configurations才能在IDE中运行并单步调试,可以很熟悉flask框架的运行原理。
- Script path : /usr/local/bin/flask
- Parameters : run
-
环境变量
- FLASK_APP = index.py
- LC_ALL = en_US.utf-8
- LANG = en_US.utf-8
本以为配置完上面三条就能运行了,因为在终端模拟器上就已经能正常运行。结果在IDE中出现了一堆莫名的错误,仔细看,大概是编码配置的问题。经搜索,还需要配置后面两个环境变量才能正常运行,大概原因是python版本2与3之间的区别。
完整代码
git clone https://github.com/zhoutk/pyrest.git
cd pyrest
export FLASK_APP=index.py
flask run
小结
今天利用flask完成了web基础架构,能够正确解析URL,提取客户端提交的数据,按请求的不同方式来组合我们需要的数据。
以上是关于用python写通用restful api service的主要内容,如果未能解决你的问题,请参考以下文章
Python——用 Django 写 restful api 接口
如何借助 Django 来编写一个 Python restful api接口
如何借助 Django 来编写一个 Python restful api接口