Featured
ccadaabfaeb

А почему мы не пишем код в контролерах?

Я думаю почти все из Вас слышали мировоззрение о том что кода в контроллерах быть не обязано, и поэтому контроллер с способами в одну строчку числятся «Best Practice».Я в свою очередь сомневаюсь в том, что полезность от этого так велика. Если у Вас появлялись похожие мысли, прошу под кат.
А почему мы не пишем код в контролерах?

Всем привет! Сходу желаю сказать что моё мировоззрение не является настоящей, и цель этого поста это высказать своё мировоззрение, и услышать комменты остальных. Все произнесенное относится в реализации API, если у вас MVC с вьюшками, то этот чемодан не сработает ибо в таком случае в контроллерах лучше писать уже лишь логику с View

Что не так?

Я буквально уверен что почти все из вас работают с обычным CRUD приложение с 3-х слойной архитектурой (больше слоев к слову нет, но о этом как то в последующий раз). И в данной для нас архитектуре у вас есть слой работы с данными (далее DA), слой бизнес логики (далее BL), и слой вью (далее VL).
BL быть может изготовлен по различному, я встречал 2 варианта

  • Class — просто класс в каком есть куча зависимостей и способы. Любой способ обрисовывает некий бизнес флоу, например передача средств, авторизация, регистрация. Этот класс употребляет наиболее низкоуровневые вещи такие как IRepository для работы с бд, разные API клиенты для остальных сервисов и тому схожее, в общем на этом слое собирают все модули вкупе и делают бизнес логику.
  • CQS — На любой бизнес флоу делают DTO (CommandQuery) классы, это просто входящие характеристики в наш обработчик. Этот метод становится наиболее популярен потому что лучше делится ответственность и этот обработчик не имеет настолько не мало зависимостей.

У этих методов есть ряд собственных правил и одно из их это то что обработчики не могут вызывать остальные обработчики, они должны быть вполне самостоятельны, буквально таковая же ситутация в реализации через обыденный класс с кучей способов, способы на столько привязаны к фиче что не могут быть переиспользованы.

Разглядим пару реализаций в этом стиле, а позже я перенесу код в контроллеры и мы проанализируем что ж мы утратили.

А почему мы не пишем код в контролерах?
А почему мы не пишем код в контролерах?

В таком виде мы реализовываем все способы и далее просто их вызываем на уровне API
А почему мы не пишем код в контролерах?

Я надеюсь вы осознаете что код с Command -> Handler будет аналогичен, просто больше разбит.

И мне вечно не дает покоя, для чего я делаю эту доп работу?

  • Что-бы переиспользовать код? — Нет, флоу перевода средств не подойдет для флоу начисления призов.
    К тому-же если вы даже отыщите возможность скооперировать 2 фичи, вы рискуете сломав одну — автоматом сломать другую
  • Что-бы перенести вызов кода в другое пространство? — Может быть, но это случается так нередко? Ну и переносить то не непременно, кто Для вас воспретил резолвить екземпляр контролера закрытым под IUserService?
  • Тестирование? Контроллеры буквально так же тестируются, а подняв TestServer вы фактически напишите end2end испытания.

А сейчас поглядим на черную магию

Давайте уберем излишнего.
А почему мы не пишем код в контролерах?
А почему мы не пишем код в контролерах?
О волшебство, код сервиса не различается от контролера, мы всего только добавили пару атрибутов и готовы ловить http запросы

Я считаю что ASP NET непревзойденно абстрагировал нас от работы с HTTP, у нас есть лучшее пространство где мы оперируем нашими типами. Повторюсь, если у Вас есть вьюшки, тогда в контроллерах лучше писать код лишь для View, а в сервисах писать переиспользуемые способы для получения данных для View. Но в текущих реалиях все почаще у нас API + SPA

Валидация?

ASP NET Core Pipeline весьма отлично тюнится и имеет массу решений, посмотрите на FluentValidation, вы добавите валилдацию даже не меняя кода в контроллерах.

Желаете больше разделения?

Делите интерфейс и если необходимо реализацию тоже.

А почему мы не пишем код в контролерах?

Как приз, интерфейс сервиса становится договором верхнего уровня, и в рамках 1-го процесса это просто прямой вызов кода из контроллера, в рамках общение клиент-сервер подставляется обычная реализация того-же интерфейса с внедрением HttpClient.

Подключение остальных каналов

Если мне произнесут что у нас может покажется ещё один канал, например через очередь, я просто могу получить екземпляр контроллера и применять его в другом канале. Этот контроллер просто резолвится из DI. Не считая того ASP NET довольно гибкий и некие каналы можно обучить его обрабатывать самому, снова таки модифицируя пайплайн.
А почему мы не пишем код в контролерах?

Смешной факт

Тестовое задание в таком стиле много где выбросят и Для вас откажут, а ведь у Вас много резонов почему вы так сделали, но если вы попадете на собеседование и обсудите почему так дизайните код, то быстрее всего это не плохое пространство и перед вами таковой же спец который соображает, что программирование многогранное

Итого

Переиспользовать можно лишь сервисы по типу репозитория, кеша, апи клиента и тд, но переиспользовать логику обработки 1-го запроса — это оооочень редчайший чемодан, и быстрее всего нехороший.

Этот подход как и остальные необходимо использовать в подходящих местах, он сберегает время, и весьма комфортен для закрытых от общественного доступа API (микросервисов).

Я считаю что контроллеры это и есть те же BL Service либо CommandQueryHandler, и в собственных проектах я практикую этот подход и контролеры делю весьма отлично, рекомендую и Для вас испытать.
Ответственность фреймворка мы ни как не прирастили, у него была задачка

  • Принимать запросы
  • Маппить их в модели
  • Вызывать обозначенный нами код по каким то правилам
  • Отдавать ответы
  • Она у него и осталась

    Я вправду не вижу критичных заморочек почему так недозволено созодать, поэтому приглашаю вас в комменты.
    Если меня не очень закидают то след статья будет о интерфейсах на любом классе-сервисе системы, и необходимо ли это? Стоит писать решение ради того чтобы было удобнее пукнуть мокнуть.

    Источник

    Zeen is a next generation WordPress theme. It’s powerful, beautifully designed and comes with everything you need to engage your visitors and increase conversions.

    Ещё
    Берлинале отказался от разделения актерских наград по гендерному признаку