flask-classy の基本的な利用方法


# 本記事で扱うこと

* flask-classyの基本的な利用方法

# 本記事で扱わないこと

* flaskの利用方法
* flask-classyでのendpointの扱い
* flask-classyでの1メソッドに対する複数ルーティングの割り当て
* flask-classyでのサブドメインの扱い方

以下の記事は、flask-classyを普段から利用していて書いているわけではなく、必要に駆られ勉強しつつ書いています。
間違いを発見した場合は、編集リクエストを投げつけるか、コメントで指摘をしていただければと思います。
よろしくお願いいたします。

# flask-classyとは

pythonで利用できる軽量webフレームワークにflaskがあります。

flaskを利用する際、通常はデコレーターと関数を利用してアプリケーションを作成していくのですが、大きめのwebアプリケーションを複数ファイルにまたがって作成しようとした時は、Blueprintと言うやつを利用してゴニョゴニョといじる必要があります。

その、ゴニョゴニョといじる手間を省き、ルーティングに関する統一された作法を導入できるのがFlask-Classyです。

# 公式ページ

https://pythonhosted.org/Flask-Classy/

上記のページを参考にざっくりと記述していきます。

# インストール

```bash
pip install flask-classy
```


# 最低限の利用方法

1. 通常のflaskの利用方法通りにFlaskクラスのインスタンスを生成する
2. FlaskViewを継承したクラスを作成する。 
3. **Flaskクラスのインスタンスを引数に、作成したクラスのクラスメソッド```register```を利用する**
4. アプリケーションの起動

```python3

from flask import Flask
from flask.ext.classy import FlaskView

app = Flask(__name__)

class HelloView(FlaskView):
    def index(self):
        return "hello world"

HelloView.register(app)

if __name__ == '__main__':
    app.run()
```

上記のファイルをコマンドラインから起動すると```localhost:5000/hello```にアクセスでき、```hello world```という文字列が確認できるはずです。


以降のサンプルでは```3```のregisterの過程はスキップされているので気をつけてください。

# ルーティングと命名規則

## クラスの命名規則

```FlaskView``` を継承したクラス名には、suffixとして ```View``` を使うことができます。

```HelloView```　に対応するurlは ```/hello/``` となります。

「使うことができる」なので、suffixを使わなくても問題なく

```FlaskView``` を継承した ```Hello``` クラスを作成しても、対応するURLは ```/hello/``` となります。


## メソッドの命名規則

最低限の利用方法でも登場していますが、FlaskViewを継承しているクラスの内、以下のメソッドは予めルーティングが決められています。

|メソッド名|ルーティング|httpメソッド|
|----|---|---|
|index|/クラス定義/|get|
|get|/クラス定義/|get|
|post|/クラス定義/|post|
|put|/クラス定義/|put|
|patch|/クラス定義/|patch|
|delete|/クラス定義/|delete|

Pythonの通常の命名規則に加えて、以下のメソッド名はFlaskViewで利用しているので利用は避けたほうがいいと思われます。

* build_route_name
* build_rule
* decorators
* get_route_base
* make_proxy_method
* parse_options
* register
* route_base
* route_prefix
* trailing_slash

上記以外のメソッド名は以下のようにアクセス出来ます。

|URL|httpメソッド|
|---|---|
|```/クラス定義/メソッド名```|get|


また他にいくつか特殊なメソッド名が定義されています。

|メソッド名|機能|
|---|---|
|before_request|クラス内で定義されているメソッドの実行前に実行される|
|before_対象メソッド名|クラス内で定義されている対象メソッドの実行前に実行される|
|after_request|クラス内で定義されているメソッドの実行後に実行される|
|after_対象メソッド名|クラス内で定義されている対象メソッドの実行後に実行される|



# ライフサイクル

1. @app.before_request
2. class.before_request
3. class.before_対象メソッド
4. class.対象メソッド
5. class.after_対象メソッド
6. class.after_request
7. @app.after_request

の順番となる



# ルーティングのオーバーライド

クラス名や関数名でURLが決まりますが、それを回避したい時の策を紹介します。

## クラス名からのルーティングを上書きする

方法は2つあります

### クラス変数として、```route_base```を宣言する

```python3
class HelloView(FlaskView):
    route_base='/'
```

### registerに```route_base```を引数として渡す

```python3
HelloView.register(app, route_base='/')
```

上記の2つはどちらもクラス名から定義されるはずの ```/hello```を上書きし、```/```でアクセス出来るようにします。

## メソッドのルーティングを上書きする

こちらは方法が一つです

```python3
from flask.ext.classy import FlaskView, route

class HelloView(FlaskView):
	@route('/hoge/')
    def index(self):
        return 'hello'
```


上記の様に、```FlaskView```を継承したクラスのメソッドに対して、```flask.ext.classy```内で定義されている```route```を利用してデコレーションしてやるとルーティングが上書きできます。

上記のサンプルの場合、urlを```/hello/hoge/```とした場合アクセス出来ます。


# HTTPメソッド

```flask.ext.classsy```　routeは ```flask``` の ```route``` と全く同じ引数を取れます。

**通常のflask同様、メソッドとルーティングを定義しただけでは、GETアクセスしか出来ません。**

GET以外のhttpメソッドを追加したい場合は、```@route```の引数に```methods```という名前で、listを渡しましょう。

とりあえず、listの要素にはどのような文字列が来ても大丈夫みたい(要検証)ですが、大丈夫なだけで得は無いと思います。
普通のHTTPメソッドを入れましょう。


以下がサンプルです。


```python3
from flask.ext.classy import FlaskView, route

class HelloView(FlaskView):
	@route('/index/', methods=['GET','POST'])
    def index(self):
        return 'hello'
```

上記の様に、```methods```を追加することで対応するHTTPメソッドでのアクセスが可能となります。