2021年7月22日木曜日

Flask 内部で別の API をコールしたい場合はモジュールやメソッドとして切り出す必要がある

Flask 内部で別の API をコールしたい場合はモジュールやメソッドとして切り出す必要がある

概要

Flask で作成した API を他のルーティングからコールしたいケースはあると思います 本来は HTTP Client などを使ってちゃんとコールしたいところですがさすがにできなさそうなのでそういった場合は共通する処理をモジュールやメソッドとして切り出すしかなさそうです

環境

  • macOS 11.4
  • Python 3.8.3
  • flask 1.1.2

サンプルコード

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 件のコメント:

コメントを投稿