В документации говорится:
Команда Grails препятствует встраиванию логики базового приложения в контроллерах, поскольку она не способствует повторному использованию и чистому разделению проблем.
У меня есть один контроллер API и несколько классов Groovy в src/groovy папке. Те классы просто реализуют мою прикладную логику так действия в работах контроллера API таким образом:
//index page
def index = {
render new IndexApi().index(params) as JSON
}
Мне любопытно - там какая-либо причина переместить мою прикладную логику от простых отличных классов на службы?
Если вы хотите транзакционное поведение, вы должны поместить свою логику в Services. В противном случае вам придется заботиться об этом самостоятельно, что не в духе использования Grails.
Будучи сам не экспертом по Grails, я разместил свои "не транзакционные" классы вне слоя сервисов, например, классы-конструкторы, хелперы и другую логику, которая не является транзакционной, но используется из слоя сервисов.
На самом деле сервисы - это не только транзакции. Сервисы отлично подходят для инжектируемых синглтонных компонентов с нулевой конфигурацией, и они могут быть перезагружены без перезапуска всего окружения grails, И они могут быть обнаружены как артефакты и, следовательно, автоматически открыты с помощью плагинов удаленного доступа.
Есть три причины:
Это делает контроллер меньше -> легче понять и поддерживать
Это упрощает проверку логики.
Вы действительно не хотите управлять своими транзакциями вручную.
Если бы вы поместили все в контроллер, вам нужно было бы создать среду выполнения Web, чтобы иметь возможность запускать любой тест. Если ваша логика находится снаружи, вы можете скопировать нужные данные из HTTP-запроса и всех других источников и просто вызвать код. Таким образом, логика не зависит от HTTP-сеансов, запросов или чего-либо еще, чего вы не хотите.
Например, для тестирования JSP вам понадобится HTTPRequest. Для запроса вам понадобятся HTTPSession и JSPWriter. Им нужен контекст сеанса. Итак, чтобы иметь возможность запустить один тест, вам нужно настроить и инициализировать целую группу классов. И все это интерфейсы, а реализации - частные. Таким образом, вы должны реализовать фактические методы (все 300 из них) самостоятельно. И вам лучше сделать это правильно, иначе ваши тесты не будут проверять то, что вы хотите.