Проблема именования переменных и структуры зависимостей при работе с JWT-токенами в FastAPI

    Столкнулся со следующей архитектурной проблемой при разработке эндпоинта обновления токенов.

    Текущая реализация

    Имеется эндпоинт для обновления access-токена:

    @app.post('/refresh')
    @limiter.limit("10/minute")
    async def refresh(request: Request, token: str = Depends(check_refresh_token)):
        access_token = create_access_token({"sub": token})
        pass

    Зависимость check_refresh_token выполняет валидацию refresh-токена и возвращает username:

    def check_refresh_token(token: str = Depends(oauth2_scheme)):
        # логика валидации токена
        return payload.get("sub")

    Суть проблемы

    Возникает семантическое противоречие:

    • Эндпоинт ожидает параметр с именем token, который по логике должен быть JWT-токеном
    • Однако зависимость check_refresh_token возвращает не токен, а username, извлеченный из payload
    • В теле эндпоинта переменная token фактически содержит username, что создает путаницу при чтении кода: create_access_token({"sub": token})

    Возможные решения

    Рассматриваю несколько подходов:

    1. Локальное переименование: внутри эндпоинта явно переименовать переменную:
      username = token
      Недостаток: решение точечное, не решает архитектурную проблему.
    2. Возврат полного payload: изменить зависимость на возврат всего payload, а в эндпоинте извлекать нужное поле:
      def check_refresh_token(token: str = Depends(oauth2_scheme)):
      # логика
      return payload

      # В эндпоинте:
      username = token.get("sub")

      Преимущество: более гибко, сохраняется доступ ко всем данным токена.
    3. Использование Pydantic моделей: создать модель для данных токена и возвращать ее экземпляр.

    Архитектурный вопрос

    Подобные ситуации часто указывают на необходимость:

    • Более четкого разделения ответственности между слоями
    • Улучшения семантики именования переменных
    • Создания специализированных DTO (Data Transfer Objects) для передачи данных между компонентами

    Какой подход считается наиболее правильным с точки зрения чистого кода и поддерживаемости FastAPI-приложений? Существуют ли общепринятые паттерны для подобных случаев?