困ったこと
fastAPI でリクエストでは異なるデータを受け取っているのに、内部で作成されるインスタンスはずっと同じインスタンスが参照されていた
原因
Python においてクラスのデフォルト引数が None 以外の場合、初期化されるタイミングは、クラスインスタンスが作成される 1 度のみであるため
そのため、リクエスト間でインスタンスが共有されていたのです
これは fastAPI の仕様ではなく、Python 言語の仕様です
例
class ApplicationAggregate:
def __init__(self, id: str, secret_key: str = "") -> None:
self.__id = ApplicationId(id) # ULIDを生成
self.__secret_key = secret_key
def get_id_of_private_value(self) -> str:
return self.__id.get_id_of_private_value()
def get_secret_key_of_private_value(self) -> str:
return self.__secret_key
app = ApplicationAggregate()
以上のようなクラスを fastAPI 上のリクエスト間で生成する場合、サーバを再実行するまでインスタンスである app は同じ ULID を保持することになります
対処法
デフォルト引数を None にしてインスタンス定義のたびに初期化を行うようにする
class ApplicationAggregate:
def __init__(self, id: str, secret_key: Optional[str] = None) -> None:
self.__id = ApplicationId(id) # ULIDを生成
self.__secret_key = secret_key if secret_key is not None else ""
def get_id_of_private_value(self) -> str:
return self.__id.get_id_of_private_value()
def get_secret_key_of_private_value(self) -> str:
return self.__secret_key
app = ApplicationAggregate()
こうすることにより、インスタンスが定義されるたびに初期化され、リクエスト間でインスタンスが共有されることはなくなります