Проектирую FastAPI-приложение с SQLAlchemy (async). Столкнулся с двумя связанными вопросами по архитектуре сервисного слоя.
Вопрос 1: где хранить сессию?
Вариант А - сессия в конструкторе:
class MealService:
def __init__(self, session: AsyncSession) -> None:
self.session = session
async def get(self, id: int) -> Meal: ...
Вариант Б - сессия как аргумент каждого метода:
class MealService:
async def get(self, session: AsyncSession, id: int) -> Meal: ...
Вопрос 2: синглтон или per-request?
Вариант А - per-request через Depends:
def get_meal_service(session: AsyncSession = Depends(get_session)) -> MealService:
return MealService(session)
Вариант Б - синглтон:
meal_service = MealService()
# в роутере
async def get_meal(id: int, session: AsyncSession = Depends(get_session)):
return await meal_service.get(session, id)
Какой подход считается более правильным для FastAPI-проектов и почему? Есть ли ситуации, когда один вариант однозначно предпочтительнее другого?