Я не уверен, что является лучшей практикой на других языках, но в PHP я использую множество Action Domain Responder Modeling в качестве архитектуры. Таким образом, база данных на 100% удалена от моего контроллера и логики просмотра. Это выглядит как ты описал.
Всякий раз, когда я хочу добавить сценарий cli или API, основанный на бизнес-логике, я использую домен вместо базы данных. Таким образом, вы не повторяете себя и можете сосредоточиться на бизнес-логике, а не на том, как отображать или обрабатывать ввод и вывод.
В контроллере, где рендерить html, я сосредотачиваюсь только на запросе и ответе. Остальное отвлечено прочь.
В сценарии CLI я снова фокусируюсь на вводе и выводе и вызываю ту же бизнес-логику.
В API я снова фокусируюсь на вводе и выводе и вызываю ту же бизнес-логику.
Таким образом, всякий раз, когда бизнес-логика должна измениться, покрываются все 3 конечные точки (html, api и cli).