[Dd]enzow(ill)? with DB and Python

DBとか資格とかPythonとかの話をつらつらと

Pythonで一番小さいWEBフレームワークbottle.py その2(ルーティング)

前回はBottleの導入からほんとに初歩の部分をまとめました。今回はルーティングの部分についてまとめていきます。

ルーティング

ブラウザなどから、リクエストされたURLに対して何の処理を割り当てるかというのがルーティングのざっくりとした意味です。イメージはこんな感じです。

URL 呼び出される処理
http://xxxxx/hello hello_func()
http://xxxxx/index index_func()

静的ルーティング・動的ルーティング

これは静的ルーティングというものです。では、/hello/hanakoであればhanakoへの挨拶、/hello/taroであればtaroへの挨拶を返す処理を考えた時、静的ルーティングの場合は以下のようになります。

URL 呼び出される処理
http://xxxxx/hello/hanako hello_hanako_func()
http://xxxxx/hello/taro hello_taro_func()

URLと、呼び出される処理の組み合わせを事前にしっかり定義しなければいけません。では、もしziroもアクセスすることになったらhello_ziro_funcの登録もしなければいけません。

本来であれば、挨拶する先だけを切り替えるのでhanakoやtaro,ziroの部分は処理の引数として渡したくなります。

URL 呼び出される処理
http://xxxxx/hello/hanako hello(hanako)
http://xxxxx/hello/taro hello(taro)
http://xxxxx/hello/ziro hello(ziro)

さらにいうと、/hello/xxxxのxxxx部分を自動的に取ってきてhelloという処理の引数に渡してほしくなります。ココで必要なのが動的ルーティングです。

Bottleでは以下の様にURLの一部分をワイルドカードの様に指定でき、それを関数の引数として取ることができます。

@route('/hello/<name>')
def index(name):
    
    # nameに応じた処理をする

動的ルーティングの書き方

上述の様に、@routeデコレータの引数で<xxxx>と書いた部分は引数として関数に引き渡すことができます。また、@routeデコレータは複数重ねることができますので以下の様な書き方ができます。 ※greetの引数にデフォルト値があるところがポイントです

@route('/')
@route('/hello/<name>')
def greet(name='Stranger'):
    return template('Hello {{name}}, how are you?', name=name)

この場合、以下の挙動になります。

URL 挙動
http://xxxx/ greet(‘Stranger’)
http://xxxx/hello/taro greet(‘taro’)
http://xxxx/hello/ Error(404)

nameに当たる部分がURLにない場合はgreet側で指定しているデフォルトの引数がそのまま使われます。

動的ルーティングの条件指定

@route('/hello/<name>')と書いた時、/hello/1でも/hello/taroでもマッチします。その際、nameはstrとして渡されます。

アプリケーションによってはURLで受け取る値は数字だけとして、それ以外は受け付けたくないケースもあると思います。Bottleではワイルドカードで受け取る値にフィルタをかけて制限することができます。

制限として使える主なものと書き方をまとめます。

制限方法 補足
数字のみ /param/<data:int> /param/1はアクセスできるが/param/aはアクセスできない
ファイルパス /param/<data:path> pathはスラッシュ付のデータを受け取れる。
/pram/hoge/lib/css.cssならdataにhoge/lib/css.cssが入る。静的ファイル配信用途が主
正規表現 /param/<data:re:[a-z]+> /param/abcdはアクセスできるが、/param/1234はアクセスできない

まとめ

ルーティングはどのWEBアプリケーションフレームワークにもありますがBottleの実装はシンプルで理解しやすいのではないかと思います。フィルタは使わなくても書けますが、使ったほうが堅牢なアプリになるので積極的に使いたい機能ですね。