Practical Python Design Patterns - The Chain of Responsibility Pattern 編
Practical Python Design Patterns - Python で学ぶデザインパターン: The Chain of Responsibility Pattern - Part. 1 「第10章: Chain of Responsibility パターン [CoR パターン]」の巻 投稿一覧へ戻る
Published 2022年6月12日19:02 by mootaro23
SUPPORT UKRAINE
- Your indifference to the act of cruelty can thrive rogue nations like Russia -
Chapter 10: Chain of Responsibility Pattern(第10章: Chain of Responsibility パターン [CoR パターン])
It wasn't me.
(ちゃっ、ちゃうねん、俺ちゃうねん!)
Overview
(概要)
Web アプリケーションは複雑で非常に手ごわい代物です。リクエストを解釈し、何をすべきかを判断しなければいけません。Web アプリケーションをより迅速に構築できるようにするためのフレームワークを作成しようとすれば、その複雑さと多岐にわたる「考慮しなければいけない事項」に打ちのめされる可能性が高いと言わざるを得ません。
Python はクラウドアプリケーション開発者に人気があるため、web フレームワークの実装言語としても主流を占めています。この章では、web フレームワークの構成要素の1つである「ミドルウェア (middleware)」を「探って」いきたいと思います。
ミドルウェアは、リクエストを送ってきたクライアントとそれに対するレスポンスを返す web アプリケーション関数の間に位置し、ミドルウェアレイヤー (middleware layer) を構築します。リクエストとレスポンス双方は必ずミドルウェアを通過しますから、後々のトラブルシューティングのためにリクエストのログを取ったり、レスポンスに対して何らかの追加操作を実行する、といったことが可能です。
一般的な使用方法としては、リクエストを送ってきたユーザーに付与されている権限によるアクセス制限の実施、アプリケーション内部での処理を容易にするためのリクエストボディに含まれているデータのフォーマット変換、ハッカーによるインジェクション攻撃を防止するための入力データのエスケープ処理、などがあります。
また、web アプリケーションにおけるルーティング処理機能 (routing mechanism) もミドルウェアの一部と考えることができます。ルーティングは、ある特定のエンドポイントに送られてきたリクエストを処理するためのコードを決定するためのメカニズムです。
ほとんどの web フレームワークでは、システム内で一貫して使用されるリクエストオブジェクト (request object) を定義・作成します。単純な定義は次のようなものでしょう:
class Request:
def __init__(self, headers, url, body, GET, POST):
self.headers = headers
self.url = url
self.body = body
self.GET = GET
self.POST = POST
def __init__(self, headers, url, body, GET, POST):
self.headers = headers
self.url = url
self.body = body
self.GET = GET
self.POST = POST
現時点では、リクエスト処理時に実行される追加操作は何1つ定義されていませんが、この単純なリクエストクラスは、web アプリケーションに対するリクエストを処理する際にミドルウェアがどのように使用されるのか、ということについての「直感」を磨くための良い土台となるはずです。
Web フレームワークは、リクエストに対する何らかのレスポンスをクライアントに返す必要があります。簡単なレスポンスクラス (response class) も定義しましょう:
class Response:
def __init__(self, headers, status_code, body):
self.headers = headers
self.status_code = status_code
self.body = body
def __init__(self, headers, status_code, body):
self.headers = headers
self.status_code = status_code
self.body = body
人気の高い Django や Flask といった web フレームワークのドキュメントを覗いてみると、それぞれのオブジェクトはここで定義したものより遥かに複雑であることが分かります。しかし、この章の学習で利用する分にはこれで十分ですので、先へ進みます。
ミドルウェアで実行したい操作の1つは、Request オブジェクトのヘッダー属性に含まれるトークン (token) 情報をチェックし、ユーザー情報 (User object) を追加する処理です。こうすることで、現在「ログイン」しているユーザーの情報にメインアプリケーションがアクセス可能となり、表示する項目などを必要に応じて変更できるようになります。
ユーザートークンを読み取り、データベースから User オブジェクトを取得するための関数を記述しましょう。この関数が返した User オブジェクトは Request オブジェクトに付加されることになるでしょう:
import User
def get_user_object(username, password):
return User.find_by_token(username, password)
def get_user_object(username, password):
return User.find_by_token(username, password)
データベースに保存するための User クラスを定義するのは簡単です。練習として SQLAlchemy プロジェクト (https://www.sqlalchemy.org/) のドキュメントを参照しながら、基本的なユーザー情報を SQLite データベースに保存するためのインターフェースを作成してみてください。この際、この User クラスには、ユニークな user token フィールドの値からユーザーを特定するためのクラスメソッドを定義するのを忘れないようにしてください。
この記事に興味のある方は次の記事にも関心を持っているようです...
- People who read this article may also be interested in following articles ... -