当サイトは、アフィリエイト広告を利用しています

【Flask】REST APIでBlueprintを使ってルーティングを整理する

作成日:2024月04月14日
更新日:2024年04月14日

FlaskのBlueprintを使ってREST APIのリソースごとに
ルーティングを整理したので使い方を忘備録として残す

Blueprintを使ったルーティング整理は

  • 通常のFlaskで作ったREST API
  • flask_restfulを使って作ったREST API

でそれぞれ実装してみる

Blueprintとは?

FlaskのBlueprintは、アプリケーションの機能を複数のファイル(モジュール)に分割するための機能。
FlaskでREST APIをつくるとき、リソースごとにルーティングを分割して整理することができる

Blueprintで通常FlaskのREST APIのルーティングを分割する

実際にBlueprintを使って通常FlaskREST APIのルーティングをリソースごとに
分割して整理してみる

Flask製のREST APIをdockerコンテナを使って作る方法については
下記で詳しくまとめている

Blueprintのインストール

pipでflaskをインストールしていれば使うことができる

インストール
pip install flask

分割前

usersとbooksのリソースに対しての簡単なREST APIを作る

構成

ディレクトリ構成は下記になる

構成
.
├── api
│ └── api.py

分割前ソース

現状ではリソースごとに分割されていない

api.py
from flask import Flask
# flaskインスタンス作成
api = Flask(__name__)
# usersリソース
users = [
{"user_id": "1", "name": "tujimura", "age": 11},
{"user_id": "2", "name": "mori", "age": 20},
{"user_id": "3", "name": "shimada", "age": 50},
{"user_id": "4", "name": "kyogoku", "age": 70}]
# booksリソース
books = [
{"book_id": "1", "book_name": "凍りのクジラ"},
{"book_id": "2", "book_name": "全てがFになる"},
{"book_id": "3", "book_name": "占星術殺人事件"},
{"book_id": "4", "book_name": "姑獲鳥の夏"}]
# usersルーティング
@api.route('/users', methods=['GET'])
def get_users():
# 取得
return users
# booksルーティング
@api.route('/books', methods=['GET'])
def get_books():
# 取得
return books

このぐらいなら問題ないが、リソースが増えて、エンドポイントも
増えていくとややこしくなるので、リソースごとにblueprintを
使って分割してみる

blueprintで分割する

下記のような構成にする

構成
.
├── api
│ ├── api.py
│ └── api_resource
│ ├── __init___.py
│ ├── booksAPI.py
│ └── userAPI.py

api_resourceを作成し、その配下にリソースごとのファイル

  • booksAPI.py
  • userAPI.py

を作成する

api_resourceをパッケージとして認識させるため
init_.pyも作成する※中身は空でOK

またapi.pyも中身は変更する

userAPI.py

usersリソースに対するルーティングをbluprintでファイル分割して
切り出す

userAPI.py
from flask import Blueprint
# blueprintインスタンス作成(users)
bp = Blueprint('users', __name__)
# usersリソース
users = [
{"user_id": "1", "name": "tujimura", "age": 11},
{"user_id": "2", "name": "mori", "age": 20},
{"user_id": "3", "name": "shimada", "age": 50},
{"user_id": "4", "name": "kyogoku", "age": 70}]
# usersルーティング
@bp.route('/users', methods=['GET'])
def get_users():
# 取得
return users
  • Blueprintインスタンスを生成
  • Blueprintインスタンスに対してルーティングを行う

booksAPI.py

booksリソースに対するルーティングをbluprintでファイル分割して
切り出す

booksAPI.py
from flask import Blueprint
from flask_restful import Api, Resource
# blueprintインスタンス作成(books)
bp = Blueprint('books', __name__)
# booksリソース
books = [
{"book_id": "1", "book_name": "凍りのクジラ"},
{"book_id": "2", "book_name": "全てがFになる"},
{"book_id": "3", "book_name": "占星術殺人事件"},
{"book_id": "4", "book_name": "姑獲鳥の夏"}]
# booksルーティング
@bp.route('/books', methods=['GET'])
def get_books():
# 取得
return books
  • Blueprintインスタンスを生成
  • Blueprintインスタンスに対してルーティングを行う

blueprintインスタンス作成について

Blueprint使う時は最初に下記のようにblueprintインスタンスを生成する

Blueprintインスタンス作成
bp = Blueprint('users', __name__)

第一引数

第一引数はBlueprintの名前を指定する
これはFlaskアプリケーション内でBlueprintを一意に識別するために
使用されるため他のBlueprintインスタンスと重複させるとエラーになる

第二引数

お決まりのパターン。
余程、特殊な場合でないname以外を設定することはない

api.py

api.pyではリソースを分割して作成したblueprintインスタンスをimportして
flaskインスタンスに登録する

api.py
from flask import Flask
from api_resource import userAPI
from api_resource import booksAPI
# flaskインスタンス作成
api = Flask(__name__)
# flaskインスタンスにblueprintインスタンスを登録
api.register_blueprint(userAPI.bp, url_prefix = '/api')
api.register_blueprint(booksAPI.bp, url_prefix = '/api')
if __name__ == "__main__":
# flaskサーバーを起動
api.run()
  • api_resourceパッケージのuserAPIモジュールとbooksAPIモジュールをimport
  • userAPIモジュールのbpインスタンス(users)をflaskインスタンスに登録
  • booksAPIモジュールのbpインスタンス(books)をflaskインスタンスに登録

flaskインスタンスにblueprintインスタンスを登録について

register_blueprintでは

  • 第一引数にblueprintインスタンス
  • 第二引数にURLプレフィックスを設定する※なくてもいい

を設定する

エンドポイントは、この場合はそれぞれ

  • /api/users
  • /api/books

になる
※ドメインとポートは除く。例えばローカル起動してる場合だと「localhost:5000/」になる

Blueprintでflask_restfulのREST APIのルーティングを分割する

REST APIを効率的に実装するためのライブラリである「Flask-RESTful」を使って
作られたREST APIをBlueprintを使ってファイル分割し、ルーティングを整理する
※Blueprintのインストール方法は同じのため割愛する

flask_restfulについて下記記事で詳しくまとめています

分割前

usersとbooksのリソースに対してのflask_restfulで簡単なREST APIを作る

構成

ディレクトリ構成は下記になる

構成
.
├── api
│ └── api.py

分割前ソース

リソースごとに分割されていない

py
from flask import Flask
from flask_restful import Api, Resource
# flaskインスタンス作成
api = Flask(__name__)
# flask_restfulのApiインスタンス作成
flask_api = Api(api)
# usersリソース
users = [
{"user_id": "1", "name": "tujimura", "age": 11},
{"user_id": "2", "name": "mori", "age": 20},
{"user_id": "3", "name": "shimada", "age": 50},
{"user_id": "4", "name": "kyogoku", "age": 70}]
# booksリソース
books = [
{"book_id": "1", "book_name": "凍りのクジラ"},
{"book_id": "2", "book_name": "全てがFになる"},
{"book_id": "3", "book_name": "占星術殺人事件"},
{"book_id": "4", "book_name": "姑獲鳥の夏"}]
# usersルーティング
class UserAPI(Resource):
# 取得
def get(self):
return users
# booksルーティング
class BooksAPI(Resource):
# 取得
def get(self):
return books
# エンドポイントを設定
flask_api.add_resource(UserAPI, '/users')
flask_api.add_resource(BooksAPI, '/books')

blueprintで分割する

下記のような構成にする

構成
.
├── api
│ ├── api.py
│ └── api_resource
│ ├── __init___.py
│ ├── booksAPI.py
│ └── userAPI.py

api_resourceを作成し、その配下にリソースごとのファイル

  • booksAPI.py
  • userAPI.py

を作成する

api_resourceをパッケージとして認識させるため
init_.pyも作成する※中身は空でOK

またapi.pyも中身は変更する

ここまでは、ほぼ通常のFlaskのREST APIでBlueprintを使う場合と同じ

userAPI.py

usersリソースに対するルーティングをbluprintでファイル分割して
切り出す

userAPI.py
from flask import Blueprint
from flask_restful import Api, Resource
# blueprintインスタンス作成(users)
bp = Blueprint('users', __name__)
# flask_restfulのApiインスタンス作成
# blueprintインスタンスを紐づける
flask_api = Api(bp)
# usersリソース
users = [
{"user_id": "1", "name": "tujimura", "age": 11},
{"user_id": "2", "name": "mori", "age": 20},
{"user_id": "3", "name": "shimada", "age": 50},
{"user_id": "4", "name": "kyogoku", "age": 70}]
# usersルーティング
class UserAPI(Resource):
# 取得
def get(self):
return users
# エンドポイントを設定
flask_api.add_resource(UserAPI, '/users')
  • Blueprintインスタンスを生成
  • flask_restfulのApiインスタンス作成時にBlueprintインスタンスを紐づける
  • Apiインスタンスに対してルーティングを行う

booksAPI.py

booksリソースに対するルーティングをbluprintでファイル分割して
切り出す

booksAPI.py
from flask import Blueprint
from flask_restful import Api, Resource
# blueprintインスタンス作成(books)
bp = Blueprint('books', __name__)
# flask_restfulのApiインスタンス作成
# blueprintインスタンスを紐づける
flask_api = Api(bp)
# booksリソース
books = [
{"book_id": "1", "book_name": "凍りのクジラ"},
{"book_id": "2", "book_name": "全てがFになる"},
{"book_id": "3", "book_name": "占星術殺人事件"},
{"book_id": "4", "book_name": "姑獲鳥の夏"}]
# booksルーティング
class BooksAPI(Resource):
# 取得
def get(self):
return books
# エンドポイントを設定
flask_api.add_resource(BooksAPI, '/books')
  • Blueprintインスタンスを生成
  • flask_restfulのApiインスタンス作成時にBlueprintインスタンスを紐づける
  • Apiインスタンスに対してルーティングを行う

api.py

api.pyではリソースを分割して作成したblueprintインスタンスをimportして
flaskインスタンスに登録する

api.py
from flask import Flask
from api_resource import userAPI
from api_resource import booksAPI
# flaskインスタンス作成
api = Flask(__name__)
api.register_blueprint(userAPI.bp, url_prefix = '/api')
api.register_blueprint(booksAPI.bp, url_prefix = '/api')
if __name__ == "__main__":
# flaskサーバーを起動
api.run()
  • api_resourceパッケージのuserAPIモジュールとbooksAPIモジュールをimport
  • userAPIモジュールのbpインスタンス(users)をflaskインスタンスに登録
  • booksAPIモジュールのbpインスタンス(books)をflaskインスタンスに登録

flaskインスタンスにblueprintインスタンスとApiインスタンスについて

通常のFlaskで作ったREST APIではblueprintインスタンス内でルーティングを行っていたため
flaskインスタンスにblueprintインスタンスを紐づけるだけでよかった。
下記のようなイメージ

通常のFlaskで作ったRESTAPI
── flaskインスタンス
├── blueprintインスタンス(users)
└── blueprintインスタンス(books)

flask_restfulの場合はルーティングを行っているのは
flask_restfulのApiインスタンスであるため、flaskインスタンスとApiインスタンスは
blueprintインスタンスを介して紐づけている 下記のようなイメージ

flask_restfulのRESTAPI
── flaskインスタンス
├── blueprintインスタンス(users) ── Apiインスタンス(users)
└── blueprintインスタンス(books) ── Apiインスタンス(books)

まとめ

blueprintの使い方をREST APIをサンプルにして
まとめてみた。

分割後にディレクトリ構造についてはわかりやすいように
作ったのでプロジェクトやリソースの数によって適宜、調整する必要がある。

参考

関連記事

新着記事

タグ別一覧
top