0
0

リクエスト間でクラスインスタンスが共有されてしまう

Last updated at Posted at 2024-04-06

困ったこと

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()

こうすることにより、インスタンスが定義されるたびに初期化され、リクエスト間でインスタンスが共有されることはなくなります

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0