用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,提取客戶端提交的數據,按請求的不一樣方式來組合咱們須要的數據。

相關文章
相關標籤/搜索