Каков правильный дизайн для системы с внешней базой данных и веб-интерфейсом и сервисом RESTful? - PullRequest
4 голосов
/ 16 декабря 2011

По сути, я начал разрабатывать свой проект так:

  1. Играть!Каркас для веб-интерфейса (использует RESTful-сервис)
  2. Spray Framework для сервиса RESTful, подключается к базе данных, обрабатывает входящие данные, обслуживает данные для веб-интерфейса
  3. База данных.Только сервис имеет права доступа к нему

Теперь мне интересно, действительно ли это лучший дизайн.На самом деле с Play!Я мог бы легко разместить и веб-интерфейс, и сервис.Это было бы намного проще для тестирования и развертывания в простых случаях, вероятно.В сложных случаях, когда требуется высокая производительность, я все еще могу запустить один экземпляр исключительно для графического интерфейса пользователя, а несколько - просто для работы в качестве сервисов (даже если каждый из них может по-прежнему обслуживать полную функциональность).
С другой стороны, я не уверенесли это не будет сильно влиять на производительность (сервисы будут обрабатывать много данных, не только из веб-интерфейса).Кроме того, разве это не смешивает вещи, которые я должен держать отдельно?

Если я решу держать их отдельно, я должен разрешить подключаться к базе данных только через службу RESTful?Как решить проблему с сервисом и веб-интерфейсом, пытаясь использовать другую версию базы данных?Должен ли я использовать протокол REST с поддержкой версий в этом случае?

----------------- РЕДАКТИРОВАТЬ -----------------

Моя текущая структура системы выглядит следующим образом:

enter image description here

Но мне интересно, не будет ли смысла упростить ее, поставив службу RESTfulвнутри Play!GUI веб-сервер напрямую.

----------------- РЕДАКТИРОВАТЬ 2 ------------------

Вот диаграмма, которая иллюстрирует мой главный вопрос.Проще говоря, другими словами: было бы плохо соединить мой сервис и веб-интерфейс и поделиться моделью?И почему?Потому что также есть несколько преимуществ:

  • меньше конфигурации между сервисом и графическим интерфейсом
  • передача данных не требуется
  • нет необходимости создавать отдельный уровень доступа (который может бытьМожет быть, недостаток, но в каком случае?)
  • нет несоответствий между моделью графического интерфейса пользователя / службы (например, из-за разных версий протокола)
  • проще для тестирования и развертывания
  • без кодадублирование (обычно нам нужно дублировать большую часть модели)

Тем не менее, вот схема:
enter image description here

Ответы [ 3 ]

1 голос
/ 17 декабря 2011

Ну, после нескольких часов размышлений об этом, я думаю, что нашел решение, которое удовлетворит мои потребности. Цели, которые я хочу достичь:

  1. Веб-интерфейс не может выполнять прямые вызовы в базу данных; необходимо использовать правильную модель, которая в свою очередь будет использовать репозиторий некоторых объектов
  2. Должна быть возможность протестировать и развернуть все как один пакет с минимальной конфигурацией (по крайней мере, на этапе разработки, а затем должна быть возможность простого переключения на более гибкое решение)
  3. Не должно быть дублирования кода (т. Е. Один и тот же код в сервисе и модели веб-интерфейса)
  4. Если один из подходов окажется неправильным, мне нужно переключиться на другой

То, что я забыл сказать ранее, - это то, что в моей службе будет встроенный кэш, используемый для агрегирования и обработки данных, а затем для фиксации в базе данных с большими кусками. Это также присутствует на диаграмме.

Моя структура классов будет выглядеть так:

| 
|- models
    |- IElementsRepository.scala
    |- ElementsRepositoryJSON.scala
    |- ElementsRepositoryDB.scala
    |- Element.scala
    |- Service
         |- Element.scala
    |- Web
         |- Element.scala
|- controlers
    |- Element.scala
|- views
    |- Element
         |- index.scala.html

Так что это похоже на обычное веб-приложение MVC, за исключением того факта, что существуют отдельные классы моделей для сервиса и веб-интерфейса, унаследованные от основного.
В Element.scala у меня будет объект IElementsRepository, внедренный с использованием DI (возможно, с использованием Guice).
IElementsRepository имеет две конкретные реализации:

  1. ElementsRepositoryJSON позволяет получать данные из службы через JSON
  2. ElementsRepositoryDB позволяет извлекать данные из локального кэша и БД.

Это означает, что в зависимости от активной конфигурации DI сервис и веб-интерфейс могут получать данные из другого сервиса или локального / внешнего хранилища.
Так что для раннего развития я могу держать все в одной игре! создайте экземпляр и используйте прямой доступ к кешу и базе данных (через ElementsRepositoryDB), а затем перенастройте веб-интерфейс для использования JSON (через ElementsRepositoryJSON). Это также позволяет мне запускать графический интерфейс и сервис как отдельные экземпляры, если я хочу. Я даже могу настроить службу для использования других служб в качестве поставщиков данных (однако пока у меня нет таких потребностей).

Более или менее это будет выглядеть так:

enter image description here

1 голос
/ 16 декабря 2011

Зачем вам нужен сервис RESTful для подключения к базе данных? Мост Играй! приложения обращаются к базе данных напрямую из контроллеров. Играть! Философия рассматривает доступ к вашим моделям через уровень обслуживания как антишаблон. Служебный уровень может быть полезен, если вы собираетесь поделиться этими данными с другими (не Play!) Приложениями или внешними системами, находящимися вне вашего контроля, но в противном случае лучше сохранить простоту. Но вы также можете просто выставить интерфейс RESTful из Play! Само приложение для других систем.

Играть! о том, чтобы упростить задачу и избежать чрезмерной чуши, которая мешала разработке Java в прошлом.

0 голосов
/ 17 декабря 2011

Ну, я думаю, что здесь нет объективно правильного или неправильного ответа, но я выскажу свое мнение: я думаю, что диаграмма, которую вы предоставили, является абсолютно правильной. Ваша служба RESTful является единой точкой доступа для всех клиентов, включая веб-интерфейс, и я бы сказал, что так и должно быть.

Не говоря уже о Play !, Spray или любых других веб-фреймворках (или, если уж на то пошло, серверах баз данных, библиотеках HTML-шаблонов, парсерах JSON и т. Д.), Очевидное правило - поддерживать строгое разделение задач. сохраняя детали реализации от утечки в ваши интерфейсы. Теперь вы подняли две проблемы:

  • Производительность: Процесс маршалинга и демаршаллинга объектов в представления JSON и их обслуживания по HTTP довольно быстрый (по сравнению с JAXB, например) и хорошо поддерживается библиотеками Scala и веб-фреймворками. Когда вы неизбежно обнаруживаете узкие места производительности в конкретном компоненте, вы можете справиться с этими узкими местами изолированно.

  • Тестирование и развертывание: Тот факт, что играть! фреймворк избегает сервлетов, это немного усложняет. Обычно я рекомендую для тестирования / постановки, что вы просто берете как WAR для вашего внешнего интерфейса, так и WAR для вашего веб-сервиса и помещаете их рядом в один и тот же контейнер сервлета. Я делал это в прошлом, например, с помощью плагина Maven Cargo . С Play !, это не так просто, но один модуль, который я нашел (и никогда не использовал), это модуль play-cargo ... Суть в том, что вы должны делать все, что нужно, чтобы слои были разъединены а затем склеить кусочки для тестирования, как вы хотите.

Надеюсь, это полезно ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...