Здравствуйте, tumblerrr, Вы писали:
T>Итого, ваш подход для ынтырпрайза, это брать html+JS и делать все максимально легким и таким каким надо.
Про легкость я ничего не говорил. Делать максимально гибким в нужных местах. Как минимум — обработка типичного транспорта. Я же не виноват, что на клиенте "строго типизированный" транспорт получается гораздо хуже, чем "универсальный на JS". Причем прямо в этом транспорте я даже "неожиданные" логические ошибки могу отслеживать (т.е. по протоколу логической ошибки на какой-то запрос не должно быть, а она есть). Что характерно, клиентский транспорт трогать не нужно при изменении протокола. В зависимости от извращенности пожеланий, может быть, в некоторых случаях нужно будет одну строчку добавить в "конфиг" для получения высокоуровневого сервиса.
T>Т.е. на каждый чих писать сервлет, формировать JSON-ы, при изменениях модели все по новой, вносим изменения в сервлет, переписываем клиент, точить свой клиент под разные браузеры и т.д. и т.п.
Не такая уж и большая работа "писать сервлет" — это один метод в уже существующий "сборник простых сервлетов" или новый класс (для замыкания на параметры) ну и еще одна (одна!) строчка для прикручивания сервлета в нужном месте биндингов. При небольших изменениях ничего в клиенте переписывать не нужно. Нужно только изменения обработать. А при больших изменениях никакой разницы нет. У вас тоже модель данных и UI придется переписывать.
И еще один замечательный момент. Я JSON по идеологическим причинам собираю вручную всегда (хотя в редких случаях можно было бы автоматически). Фокус в том, что далеко не все нужные данные ложатся 1 к 1 на запросы к базе данных. Например, ответ клиенту может собираться из двух-трех разных запросов. Да и при желании я могу строить фрагменты JSON сразу из результатов базы, а не городить DTO. Кстати, о DTO. Для сервера взята scala. Поэтому "DTO" зовется примерно так: case class SomeDTO(field1: String, field2 : Int, field3: Boolean). Парсится так: SomeDTO(rs.field1, rs.field2, rs.field3). Иногда ходят туплы, потому что DTO лишние писать лень. Так что как бы небольшая проблема.
Да, запросы принципиально не ложатся на "простую" схему данных в базе. Usecases — это не просто редактирование данных в справочнике. Так что основная задача — написать правильные запросы для базы, а остальное — мелочи и достаточно легко автоматизируется. Я даже JSON-фрагменты при желании могу с использованием метаданных базы генерировать, так что изменения будут в запросе и на клиенте, без правки java beans.
Касательно "точить под разные браузеры". Под них точится очень небольшая часть библиотек (ui, low-level network transport). Все остальное точить не надо, оно достаточно высокоуровневое и нормально работает через обертки/интеграционный слой.
T>А сколько по вашему займет времени, прежде чем велик поедет?
Какой? Зависит от того, чего в него пихать. Я без опыта html и js (только AS3, там API все же другое) поднимал прототип приложения (полноценного, с базой, клиентом и т.п.) за месяц. Притом с относительно сложной логикой отображения в некоторых местах (добавление/удаление элементов в список, редактирование зависимостей между этими элементами). И при этом я в очередной раз сделал и адаптировал библиотеку реактивного программирования (это день максимум, изначально дня два-три было и еще немного на доделку по ходу). А еще я написал аналог require.js под свои нужды (не понравился мне таймер в его дебрях, да и модули по-другому немного у меня паковались и готовились). Написал layer manager + некоторый focus manager (чтобы модальность реализовывать). Отрефакторить их смог, сделал нормальное разбиение на модули. Это все при том, что я до этого детально ни версткой, ни html не занимался (т.е. справка по css + html). Ну и логика, естественно (в том числе — реаутентификация запросов тех же). При этом я еще на что-то отвлекался... Прототип он только в том, что я не художник. Был бы у меня под рукой художник (верстальщик, конечно, лучше), было бы полноценное приложение.
T>Вот взять с нуля и начать это делать? И сколько народу понадобится для боле менее разумных сроков?
Если с нуля — через месяц велосипед будет прекрасно и резво ездить. Два-три человека достаточно. Я и художник-верстальщик. Если брать готовые компоненты (с предыдущих проектов), через 1-3 дня заведется (нужно аккуратно "стек" пересобрать с учетом конкретных потребностей), стили и то дольше переделывать (если нужно их трогать).
T>Через сколько месяцев появятся боле менее рабочие компоненты вроде гридов?
А что такое грид и зачем он вам вообще нужен? Вы ведь понимаете, что пользователю не нужен сам грид? Ему нужно выполнять какую-то задачу, и эту задачу он выполняет с помощью грида (а может, и не с его помощью). В общем виде он у меня уже давно есть в обычных компонентах:
function renderGrid(items) {
return UI.table('my-cool-grid', items.map(renderRow));
}
function renderRow(item) {
return UI.tr('my-cool-grid-row', item.cols.map(function(elt) {return UI.td('my-cool-elt', UI.text(elt))}))
}
function renderRow(item) {
return UI.tr('my-cool-grid-row',
UI.td('first-column', UI.text(item.name)),
UI.td('second-column', UI.img('user-logo', item.imageurl)));
}
Вот вам даже два варианта рендеринга строки. Чем не grid? Со штатными grid'ами проблема в том, что 90% их функциональности мне для нормальной работы не нужны. А то, что нужно, он как раз не реализует и прикрутить это туда очень и очень сложно (см. мой пример про custom completion же). При необходимости рендеринги строк/ячеек (для редактирования) тюнингуются под конкретную архитектуру фрагмента. В универсальный грид я вкладываться не буду до тех пор, пока не пойму, что он действительно универсален и решает хотя бы 80% моих задач (в других местах останется кастомный рендеринг).
T>Как у этого решения будет с безопасностью?
Прекрасно у него будет с безопасностью. Протокол открыт, на сервере состояния минимум (и то привязано к некоторому "auth token" aka session id), так что анализировать безопасность прекрасно можно. Анализировать "черный ящик" ваадина сложнее.
На сервере:
* Все ненужные для пользователя вызовы API закрыты фильтром. Так что логике не нужно ни о чем заботиться.
* Само приложение тоже почти все закрыто фильтром (открыты только входы для аутентификации).
* Форматом security token, его передачей, сроком хранения рулю я сам. Я вот могу его по secure random сгенерировать, добавить соль, сахар, протереть через SHA-1 и отдать пользователю. Поэтому "подобрать" session-id, например, не получится. А еще я могу ограничить адреса, на которые кука ходит. А могу не кукой передавать, а в запрос дописывать (goodbye CSRF!, кстати, посмотрите на форумах, как там защита от CSRF в vaadin'е включается

). Я даже могу половинку ключа кукой, а половинку — в запросе.
* Я при желании могу json-serializer поменять, например (вдруг там баги обнаружатся, когда он эскейпит не совсем правильно). Изменится в коде очень мало.
На клиенте:
* На security есть небольшой выход на нижнем уровне. Ибо транспорт должен уметь авторизовываться.
* На security есть небольшой выход на "среднем" транспортном уровне и на конфигурации. Там мы пользователя просим пользователя перелогиниться, если в доступе отказано (ну и запрос повторяем).
* И... И все, собственно. Всему остальному нет никакой разницы. Весь обмен и т.п. идет через нижние уровни. При необходимости "permissions" для отображения UI я в запросе передам или на саму страницу.
Так что по user-managed security все хорошо. Остались вопросы защиты сервера (tomcat, jetty, еtc...), но они одинаковы для всех приложений той платформы и разницы между велосипедом и vaadin'ом в этом аспекте нет.