Ответ
Контроллер в Чистой архитектуре — это компонент во внешнем слое 'Interface Adapters', который служит точкой входа для внешних систем (например, веб-фреймворка).
Его основная задача — координировать поток данных, но он не должен содержать бизнес-логики. Его обязанности включают:
- Прием и разбор входящих запросов (например, HTTP-запросов).
- Валидация и преобразование данных из формата запроса (DTO - Data Transfer Object) в доменные модели, понятные для бизнес-логики.
- Вызов соответствующего
Use Case
(сценария использования) из слоя бизнес-логики, передавая ему подготовленные данные. - Преобразование результата, полученного от
Use Case
, обратно в формат ответа (например, JSON), который будет отправлен клиенту.
Это обеспечивает соблюдение Правила Зависимостей (Dependency Rule): все зависимости направлены внутрь, к бизнес-логике. Use Cases
ничего не знают о контроллерах, HTTP или конкретных фреймворках.
Пример на Go:
// UserController находится в слое 'Interface Adapters'
type UserController struct {
createUser usecase.CreateUserUseCase // Зависимость от интерфейса Use Case
}
// CreateUser - метод контроллера, обрабатывающий HTTP-запрос
func (c *UserController) CreateUser(w http.ResponseWriter, r *http.Request) {
// 1. Разбор и валидация DTO
var req CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid request body", http.StatusBadRequest)
return
}
// 2. Преобразование DTO в доменную модель и вызов Use Case
user, err := c.createUser.Execute(r.Context(), req.ToDomain())
if err != nil {
// Обработка ошибок, пришедших от бизнес-логики
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 3. Преобразование результата в ответ
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(UserResponseFromDomain(user))
}