Применяли ли вы архитектурные подходы, например чистую архитектуру или hexagonal architecture?
Что проверяют
Применяли ли вы это на живом проекте или пересказываете статью. Честное «нет» здесь звучит нормально, а вот выученное определение без практики распознаётся с первого уточнения. Следом спрашивают конкретику: как разложены пакеты, где объявлены интерфейсы, как выглядит транзакция на несколько репозиториев.
Как отвечать
- суть: зависимости направлены внутрь. Домен и сценарии ничего не знают ни про HTTP, ни про драйвер базы. Порты это интерфейсы, адаптеры это их реализации;
- раскладка:
cmd/appсобирает зависимости,internal/domainдержит сущности и ошибки,internal/usecaseсценарии,internal/adapter/http,internal/adapter/postgres,internal/adapter/kafkaвнешний мир; - идиома Go: интерфейс объявляется у потребителя, а не рядом с реализацией.
usecaseописываетOrderRepositoryпод свои нужды, а пакетpostgresпросто ему соответствует и ничего изusecaseне импортирует; - ошибки: доменные значения-маркеры, транспорт переводит их в коды ответа через
errors.Isиerrors.As. Сценарий не должен знать про 404; - тесты: сценарии на подставных реализациях интерфейсов, адаптеры на настоящей базе через
testcontainers-go.
Сильный ответ называет и цену. Отображение между DTO, доменной сущностью и строкой таблицы пишется трижды, и для сервиса на пять эндпоинтов это дороже пользы. Скажите, где вы сознательно упростили: взяли схему handler, service, repository, а полный набор портов оставили сервису со сложными правилами.
Не применяли, так и скажите, но покажите понимание: опишите фактическую структуру своего проекта, где в ней протекает инфраструктура и что бы вы поменяли первым.
Где спотыкаются
Рисуют круги из книги, а в коде обработчик импортирует pgx и собирает SQL прямо в хендлере. Схема на доске и схема в репозитории должны совпадать.
Вешают на доменную сущность теги json и db. Домен становится зависим от формата ответа и схемы таблицы, и правка API тянет за собой правку домена.
Не могут объяснить транзакцию. Если каждый репозиторий сам берёт соединение, два вызова в одном сценарии не соберутся в одну транзакцию. Нужен либо проброс через контекст, либо метод-обёртка на уровне сценария.