Как и где в ‘Чистой архитектуре’ (Clean Architecture) описываются и реализуются API?

Ответ

В 'Чистой архитектуре' API описывается и реализуется в слое Адаптеров Интерфейсов (Interface Adapters). Это внешний слой, который преобразует данные из формата, удобного для внешнего мира (например, HTTP JSON), в формат, удобный для ядра вашего приложения (Use Cases), и обратно.

Где это находится в проекте:

Обычно это директории internal/delivery, internal/controller или internal/interfaces.

/my-project
├── cmd/app/main.go      // Точка входа
└── internal/
    ├── domain/          // Сущности и основная бизнес-логика
    ├── usecase/         // Сценарии использования (прикладная бизнес-логика)
    └── delivery/        // Слой адаптеров (API)
        ├── http/        // Адаптеры для HTTP
        │   ├── handler.go // Обработчики HTTP-запросов (хендлеры)
        │   └── router.go  // Регистрация роутов
        └── grpc/        // Адаптеры для gRPC
            └── service.go // Реализация gRPC-сервисов

В каком виде описывается API:

  • HTTP-хендлеры: Функции, которые принимают http.Request, вызывают соответствующий usecase и возвращают http.Response.
  • gRPC-сервисы: Реализации сервисов, сгенерированных из .proto файлов.
  • Спецификации OpenAPI/Swagger: Файлы в формате YAML или JSON, которые формально описывают эндпоинты, запросы и ответы. Часто размещаются рядом с HTTP-хендлерами.

Ключевой принцип: Этот слой не должен содержать бизнес-логики. Его единственная задача — адаптация данных и вызов следующего слоя (Use Cases). Это защищает бизнес-логику от изменений в способе доставки (например, при переходе с REST на gRPC).

Ответ 18+ 🔞

А, ну ты про эту самую "Чистую архитектуру"! Ну, блядь, классика жанра, ёпта. Слушай, тут всё просто, как три копейки, если не загоняться.

Вот смотри, этот твой API — он как раз тот самый слой адаптеров интерфейсов, понимаешь? То есть это такая прослойка-переговорщик между внешним миром, который хочет тебе в сраку JSON'ом настучать, и твоим священным ядром приложения, где вся бизнес-магия творится.

Где эта хуйня обычно валяется в проекте?

Да вот же она, на виду! Смотри на структуру, как на ладони:

/my-project
├── cmd/app/main.go      // Отсюда всё и начинается, точка входа, блядь
└── internal/
    ├── domain/          // Тут святое — сущности и самая сокровенная бизнес-логика. Трогать страшно.
    ├── usecase/         // А тут уже сценарии использования, прикладная логика. Тоже мозги проекта.
    └── delivery/        // А ВОТ ОН, РОДНОЙ! Слой адаптеров, твой API! Тут уже можно.
        ├── http/        // Для тех, кто любит по HTTP постучаться
        │   ├── handler.go // Собственно, хендлеры — они как швейцары: приняли request, вызвали usecase, отдали response.
        │   └── router.go  // А это кто куда идёт — роутинг, маршрутизация, всё дела.
        └── grpc/        // А это для любителей побыстрее, на gRPC
            └── service.go // Реализация тех самых сервисов из .proto файлов.

И в каком, блядь, виде этот API описывается?

Да по-разному, ёпта!

  • HTTP-хендлеры: Обычные функции, которые ловят http.Request, орут в сторону usecase: "Эй, пацаны, работа есть!", а потом упаковывают результат в http.Response. Всё.
  • gRPC-сервисы: Почти то же самое, только по-модному, по протоколу. Реализуешь то, что в .proto файле нарисовал.
  • OpenAPI/Swagger: А это, блядь, для парадного входа! Формальные бумажки в YAML или JSON, где всё по полочкам разложено: какие эндпоинты, что принимают, что отдают. Часто рядом с хендлерами лежат, чтобы не потерялись.

И главное, запомни раз и нахуй: В этом слое НИКАКОЙ, БЛЯДЬ, БИЗНЕС-ЛОГИКИ! Ноль! Его задача — чистая адаптация. Как переводчик-синхронист. Принял запрос на одном языке (HTTP/JSON), перевёл на язык usecase'ов (структуры Go), получил ответ, перевёл обратно.

Это чтобы, если вдруг завтра тебе взбредёт в голову не REST, а gRPC, или GraphQL, или, я не знаю, телепатический интерфейс делать — ты бы не переписывал всю свою бизнес-логику, а только этого самого "переводчика" поменял. Защита, блядь, от дурака и от будущего. Умно, чё.