Эта дискуссия давняя, и вы найдете разные лагеря. Я полагаю, что если у вас есть бэкэнд-система с четкой автономной функцией, вы должны сначала разработать ее с помощью API и всего остального, а затем использовать этот API из уровня представления. В этом случае наслоение гарантировано. Одним из примеров является то, что вы пишете веб-интерфейс для своего уже разработанного пользовательского программного обеспечения.
Однако в большинстве веб-приложений гораздо проще и понятнее использовать один единственный источник конфигурации. Django, RoR, JBoss Seam и другие используют этот подход. Они используют концепцию, сконцентрированную на наборе классов предметной области, в которую помещена вся логика и ограничения проверки. Исключения модели (такие как NoSuchObject) напрямую отображаются для просмотра исключения (404 Not Found), все они обрабатываются платформой. При таком подходе нет слоев, и основная идея состоит в том, чтобы избежать наслоения до тех пор, пока оно действительно не понадобится. Документы Django являются действительно хорошим источником информации по этим темам, а документы Seam более технические, но и более подробные.
Решение выставить некоторую логику в виде веб-службы не означает автоматического принятия решения о создании комплексного многоуровневого решения, здесь я бы сказал, что его легко реорганизовать.
Расслоение действительно добавляет еще одно измерение проблем, связанных с распространением информации взад и вперед, и я бы сказал, что, если она не соответствует вашей проблеме, не используйте ее.