用python写通用restful api service(一)

一直在用node.js作后端,要逐步涉猎大数据范围,注定绕不过python,所以决定把一些成熟的东西用python来重写,一是开拓思路、经过比较来深刻学习python;二是有目标,有动力,但愿能锲而不舍的坚持下去。node

项目介绍

用python语言来写一个restful api service,数据库使用mysql。由于只作后端微服务,而且ORM的实现方式,采用自动生成SQL的方式来完成,所以选择了轻量级的flask做为web框架。如此选择,主要目的是针对中小规模的网络应用,能充分利用关系数据库的种种优点,来实现丰富的现代互联网应用。python

restful api

restful api 的概念就不介绍了。这里说一下咱们实现协议形式:mysql

[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

说明:git

  • rs为资源标识;
  • 第二节,user,会被解析为数据库表名;
  • 查询时,id为空或0时,id会被忽略,即为列表查询;
  • 新建和修改,除接收form表单外,url中的id参数也会被合并到参数集合中;
  • 删除同查询。

让flask支持正则表达式

flask默认路由不支持正则表达式,而我须要截取完整的URL本身来解析,经查询,按如下步骤很容易完成任务。github

  • 使用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'])

几点疑问:web

  1. 正则(.*)理论上应该是匹配任何除回车的全部字符,但不知道为何,在这里不识别问号(?)
  2. 我用request.data来取表单数据,为什么request.form取不到?
  3. '/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组合参数集合。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
  • 环境变量json

    • 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,提取客户端提交的数据,按请求的不一样方式来组合咱们须要的数据。

相关文章
相关标签/搜索