概要
Flask で作成した API を他のルーティングからコールしたいケースはあると思います 本来は HTTP Client などを使ってちゃんとコールしたいところですがさすがにできなさそうなのでそういった場合は共通する処理をモジュールやメソッドとして切り出すしかなさそうです
環境
- macOS 11.4
- Python 3.8.3
- flask 1.1.2
サンプルコード
- vim app.py
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/abc/<x>/<y>', methods=['GET'])
def abc_route(x, y):
return jsonify(abc(x, y))
@app.route('/xyz', methods=['POST'])
def xyz():
x = request.form["x"]
y = request.form["y"]
return jsonify(abc(x, y))
def abc(x, y):
return "{}.{}".format(x, y)
動作確認
- FLASK_DEBUG=1 pipevn run flask run
GET と POST で同じ結果が返ってきます
-
curl -XPOST localhost:5000/xyz -F 'x=1' -F 'y=2'
-
curl -XGET localhost:5000/abc/1/2
ポイント
共有するモジュールが method やクエリに依存しないようにする
例えば flask では GET と POST ではパラメータの受け取り方が変わります 共有するモジュール内ではパラメータの受け取りなどはせずにパラメータをそれぞれのルーティングで受け取ったあとで引数としてパラメータを受け取るようにしましょう
共有するモジュール内でレスポンスを返さないようにする
あくまでもレスポンスを返すのはルーティング側で行うようにしましょう 同じ処理をさせたいがレスポンスは違うようにしたい場合に対応できなくなります
return などは単純な文字列や辞書型などを返却するようにして flask のレスポンスとして整形するのはルーティング側で行います
別アプリとして切り出すのもありか
例えばサンプルで言うところの abc(x, y)
を別の Flask アプリとして切り出します
そして requests などを使って RPC 的に abc をコールします
この方法であれば例えば外部向けに公開したりもできるのでより汎用的に使えるようになります
もしくは PyPi 形式で外部公開するのもありだと思います
最後に
変なことはせずに単純に考えるようにしましょう
0 件のコメント:
コメントを投稿