Всем привет!
Вышел тут спор с коллегами по поводу проектирования архитектуры java-приложения.
В общем то все тривиально: источник данных -> CRUD -> Сервисы бизнес-логики -> Rest.
Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики?
Как считаете?
Здравствуйте, sotnik, Вы писали:
S>Вышел тут спор с коллегами по поводу проектирования архитектуры java-приложения. S>В общем то все тривиально: источник данных -> CRUD -> Сервисы бизнес-логики -> Rest. S>Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики? S>Как считаете?
Подбросьте монетку. Всё равно всё потом переписывать. А так, не придётся друг-друга обвинять, что неправильное решение приняли.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
·>Подбросьте монетку. Всё равно всё потом переписывать. А так, не придётся друг-друга обвинять, что неправильное решение приняли.
Понятно, что серебряной пули здесь нет. Но почему "все равно переписывать"?
Вообще-то, я рассчитывал услышать какие-то аргументы за или против описанных подходов. Специально не стал озвучивать свою точку зрения.
Здравствуйте, sotnik, Вы писали:
S>·>Подбросьте монетку. Всё равно всё потом переписывать. А так, не придётся друг-друга обвинять, что неправильное решение приняли. S>Понятно, что серебряной пули здесь нет. Но почему "все равно переписывать"?
А шо делать!?. Жизнь такая...
S>Вообще-то, я рассчитывал услышать какие-то аргументы за или против описанных подходов. Специально не стал озвучивать свою точку зрения.
Да вроде как всё очевидно.
Экспозить бизнес-сервисы напрямую:
+ меньше кода
+ код проще
— смешивание бизнес-логики и технических деталей rest — авторизация там всякая, сериализация
— сложнее потом прикрутить другие представления: начать лепить api v2.0 или вообще решили приделать коммуникацию через MQ-сообщения
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
·>Здравствуйте, sotnik, Вы писали:
Собственно, да, такие аргументы и звучали. Теперь можно и свои мысли высказать .
·>Да вроде как всё очевидно. ·>Экспозить бизнес-сервисы напрямую: ·>+ меньше кода
согласен
·>+ код проще
здесь, мне кажется, спорно, т.к. перекликается со следующим пунктом
·>- смешивание бизнес-логики и технических деталей rest — авторизация там всякая, сериализация
именно это мне больше всего и не нравится
·>- сложнее потом прикрутить другие представления: начать лепить api v2.0 или вообще решили приделать коммуникацию через MQ-сообщения
согласен
В целом получается, что плюс — это меньше кода. Это хорошо, когда нужно быстро сделать какой-то макет. Однако, если планируется большой проект с дальнейшей поддержкой и доработкой, то экономить строчки кода как-то неправильно на мой взгляд.
Здравствуйте, sotnik, Вы писали:
S>·>+ код проще S>здесь, мне кажется, спорно, т.к. перекликается со следующим пунктом
Сразу видно что и как происходит, не надо ходить туда сюда в поисках сути.
S>·>- смешивание бизнес-логики и технических деталей rest — авторизация там всякая, сериализация S>именно это мне больше всего и не нравится
Для голого crud меньше boilerplate кода.
S>В целом получается, что плюс — это меньше кода.
Лучше меньше, да лучше.
S>Это хорошо, когда нужно быстро сделать какой-то макет. Однако, если планируется большой проект с дальнейшей поддержкой и доработкой, то экономить строчки кода как-то неправильно на мой взгляд.
Тут ведь как... KISS + рефакторинг наше ВСЁ!
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, sotnik, Вы писали:
S>Всем привет! S>Вышел тут спор с коллегами по поводу проектирования архитектуры java-приложения. S>В общем то все тривиально: источник данных -> CRUD -> Сервисы бизнес-логики -> Rest. S>Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики? S>Как считаете?
Если у вас вся архитектура "бд с веб-доступом", то просто используйте сервер бд, которая позволяет дергать хранимки через веб-запросы и всё — никакого кода писать не надо, всё будет сразу в SQL.
Здравствуйте, Vladek, Вы писали:
V>Если у вас вся архитектура "бд с веб-доступом", то просто используйте сервер бд, которая позволяет дергать хранимки через веб-запросы и всё — никакого кода писать не надо, всё будет сразу в SQL.
К сожалению не все так просто. Бизнес-логика все-таки будет на стороне приложения по ряду причин.
Здравствуйте, sotnik, Вы писали:
S>Здравствуйте, ·, Вы писали:
S>·>Здравствуйте, sotnik, Вы писали:
S>Собственно, да, такие аргументы и звучали. Теперь можно и свои мысли высказать .
S>·>Да вроде как всё очевидно. S>·>Экспозить бизнес-сервисы напрямую: S>·>+ меньше кода S>согласен
S>·>+ код проще S>здесь, мне кажется, спорно, т.к. перекликается со следующим пунктом
S>·>- смешивание бизнес-логики и технических деталей rest — авторизация там всякая, сериализация S>именно это мне больше всего и не нравится
S>·>- сложнее потом прикрутить другие представления: начать лепить api v2.0 или вообще решили приделать коммуникацию через MQ-сообщения S>согласен
S>В целом получается, что плюс — это меньше кода. Это хорошо, когда нужно быстро сделать какой-то макет. Однако, если планируется большой проект с дальнейшей поддержкой и доработкой, то экономить строчки кода как-то неправильно на мой взгляд.
А тут все и упирается в то, что будет планироваться. Если ни чего не планируется, то и мудрить не надо, написали как быстрей и проще и все.
S>Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики? S>Как считаете?
Зависит от задач и целей:
Rest-сервисы предназначены для кого?
Что можно и что нельзя потребителям Rest-сервисов?
Может ли бизнес-логика меняться без изменения сигнатур API? Как на такие изменения должны реагировать потребители API?
Может ли, наоборот, меняться API? И что при этом должно происходить?
В общем, образно выражаясь, если потребители API достаточно "тесно интегированы" в разрабатываемую систему — можно ограничиться методами бизнес-логики. Если бизнес-логика более-менее постоянна, и также не представляет какого-либо секрета — тогда тоже можно. Если же потребители API в достаточной степени "отвязаны" от системы — тогда лучше сделать для API отдельный слой.
Считаю, что архитектура — это функция от требований к проекту.
Что вы пилите, в чем основная сложность (и, соответственно, риски) вашего проекта?
От этого будет зависеть то, как "правильно" строить архитектуру в вашем конкретном случае.
Если, например, это какая-то внутренняя админка — фигачте как проще и быстрее, еще сто раз переделаете.
Если ваш основной затык — перформанс, то не важно, как будет организован доменный слой. Надо твикать БД (оптимизация, индексы, шардинг и т.п.) и думать на скейлингом (деплой, statefull/stateless инстансы и т.п.)
Если у вас сложная именно предметная область, то надо сосредоточиться на ней — реализовать доменный слой таким образом, чтобы его можно было переиспользовать с любым типом внешнего интерфейса (REST, SOAP, шина, консольный или web UI и т.п.)
А вот если пока вообще непонятно, где ваша сложность (ну бывает и такое) — фигачьте как проще и быстрее, чтобы скорее получить фидбек и отрефакториться.
Здравствуйте, sotnik, Вы писали:
S>Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики? S>Как считаете?
Отделять REST в отдельный слой.
Иначе в классы бизнес-логики будут намешаны http-пути, проверка параметров, ответы на ошибки, маршалинг. Это будет сильным тормозом как в развитии REST API, так и в развитии бизнес-логики. Ладно RPC был бы, но для REST точно надо отделять.
UPD. И с тестированием совсем плохо будет, если аннотации клепать.
Здравствуйте, sotnik, Вы писали:
S>В общем то все тривиально: источник данных -> CRUD -> Сервисы бизнес-логики -> Rest. S>Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики? S>Как считаете?
согласен с предыдущим оратором. Бизнес-логика должна жить в отдельном слое по очевидным причинам — он должен быть юнит-тестируемым. Сервисы REST будут обладать множеством специфичных то HTTP вещей, те-же аннотации, возврат различных http кодов в зависимости что там бизнес логика нарешала итп. Смешав все в кучу юнит тесты будет нереально написать
Здравствуйте, sotnik, Вы писали: S>В общем то все тривиально: источник данных -> CRUD -> Сервисы бизнес-логики -> Rest.
Гм... вообще говоря под многоуровневой архитектурой понимается несколько более сложные вещи. Ну и даже в вашем тривиальном случае по идее должно быть где-то так: источник данных --> CRUD -[REST]-> Сервисы бизнес-логики.
S>Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики? S>Как считаете?
В общем RPC получается. Так что аннотации к сервисам бизнес-логики.
PS Ну или вы под понятием "сервисы бизнес логики" понимаете что-то совершенно другое.
Всё, что нас не убивает, ещё горько об этом пожалеет.
Здравствуйте, sotnik, Вы писали:
S>В общем то все тривиально: источник данных -> CRUD -> Сервисы бизнес-логики -> Rest. S>Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики?
На моей практике строгое разделение на "сервисы" и "REST фасад" ни разу не окупилось, потому что REST так навсегда и оставался единственным фасадом. Более того, отсутствие такого разделения замечательно сработало в нескольких проектах, потому что, снова, REST так навсегда и остался единственным фасадом.
Ещё нужно понимать, что "правильный REST" накладывает довольно много ограничений на поведение того, что за ним скрывается, поэтому в общем случае нельзя просто так взять и сделать отдельно сервисы и отдельно REST-фасад для них. Но тут, конечно, зависит от того, что у вас понимается под REST.
Совсем не плохой вариант — сделать REST-only сервис, а в будущем, если понадобятся другие фасады, оформить их как адаптеры, которые взаимодействуют с сервисом через REST.
Здравствуйте, sotnik, Вы писали:
S>Всем привет! S>Вышел тут спор с коллегами по поводу проектирования архитектуры java-приложения. S>В общем то все тривиально: источник данных -> CRUD -> Сервисы бизнес-логики -> Rest. S>Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики? S>Как считаете?
Я считаю что вам не надо думать о слоях.
Создайте классы, которые от потребителя спрячут детали вызовов, аутентификации, сериализации, повторов и используйте в классах бизнес-логики.
Когда все заработает — можете начинать спор являются ли эти классы отдельным слоем или это инфраструктура.
Здравствуйте, sotnik, Вы писали:
S>Всем привет! S>Вышел тут спор с коллегами по поводу проектирования архитектуры java-приложения. S>В общем то все тривиально: источник данных -> CRUD -> Сервисы бизнес-логики -> Rest. S>Спор возник по вопросу: стоит ли выделять Rest-сервисы в отдельный слой или навесить аннотации прям на методы сервисов бизнес логики? S>Как считаете?
Стоит. И более того, нужен не просто отдельный слой, но и отдельная модель. Каждый раз, как я ленился это сделать, я об этом впоследствии жалел.
Причина — необходимость обеспечивать минимализм, функциональность, безопасность и обратную совместимость API.
Минимализм — API должно выставлять наружу только минимальный и достаточный для клиентов набор методов и данных. Если выставлять лишнее, то клиенты могут завязаться на эти данные, делая доработки сервера проблематичными. Любителям выставлять в REST хибернейтовские объекты приготовлен отдельный котёл в аду.
Функциональность — у слоя API есть своя логика, отдельная от бизнес-логики. Это логика сериализации, аудита, проверок прав доступа, кеширования. Если отказаться от слоя API, этот функционал придется писать в слое бизнес-логики и нет никакой гарантии, что метод с этой логикой не будет вызван другими методами слоя бизнес-логики.
Безопасность — Жесткий, контролируемый API важен для обеспечения безопасности API — гарантий, что все входящие запросы проходят авторизацию, что API не возвращает какие-то чувствительные данные — пароли, персональные данные и т.п. На этом пункте многие погорели, включая самые крупные компании.
Обратная совместимость — изменения, ломающие обратную совместимость, должны быть четко отделены и контролируемы. Если нет отдельного слоя API и отдельной доменной модели, как ответить на вопрос, ломает ли обратную совместимость такая-то модификация такого-то класса в бизнес-логике?
Если REST отдавать кому то наружу, то однозначно выделять, потому что требования к REST API и требования к сервисам бизнес-логики почти всегда очень разные, и пытаться все запихнуть в одну структуру — отличный путь похоронить проект в неуправляемой сложности.