Flaskで共通的なpath変数を検証する方法
/api/<lang_code>/sample
のようなurlが用意されている場合、lang_code
はすべてのurlで利用する場合を想定します。
このとき、controller側でパタメータを取得し、検証する方法もあります。
ただし、すべてのcontrollerで同じ処理を書いてしまうのは避けるべきことです。
また、うっかり実装を忘れてしまうこともあります。
apiを用意する
class based
でapiを用意しています。
本題と逸れる実装については解説を省きます。
今回はSampleApi
を用意しました。
class SampleApi(ApiResource): endpoint = 'SampleApi' url_prefix = '/api/<lang_code>/sample' methods = ['POST'] url_rules = [ UrlRule( endpoint='sample', rule='index', methods=['POST'], ) ] def post(self, lang_code): body = request.json print("called sample api.", body) return jsonify(body)
このapiをcurl
を使って実行すると以下のようになります。
curl -X POST -H "Content-Type: application/json" -d '{ "title": "sample title" }' http://127.0.0.1:8080/api/ja/sign-in/index
このときの/ja/
の部分を取得して、DBからデータを取得するなどできるようにします。
他にも、アプリケーションコンテキスト中にデータを格納できるg
に値を入れるなどできます。
url_value_preprocessorの設定を行う
Flask
を拡張して、独自の設定を追加できるclassを作成します。
from app.request_module.pre_processors import language_code class AppFlask(Flask): """Extended version of `Flask` that implements custom config class""" def init_url_value_preprocessor(self): self.url_value_preprocessor(language_code)
url_value_preprocessor
にlanguage_code
という関数を設定しています。
url_value_preprocessor
はFlask.before_request(f)
の後に実行されます。
https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.url_value_preprocessor
language_code関数を用意する
url_value_preprocessor
で登録する関数にはendpoint
とvalues
が必要です。
def language_code(endpoint, values): api_class = url_for(endpoint, lang_code="ja") if 'lang_code' in values or not g.lang_code: return
今回のSampleApi
を実行した場合、endpoint
とvalues
にはそれぞれ以下のようになります。
endpoint: SampleApi.sample values: lang_code: ja
※ yamlで書いていますが、yamlが値に入るわけではありません。
endpoint
はurl_for
で使用可能な値です。
あとはapiを実行するだけで、先程作成したlanguage_code
関数が実行されます。