What is the correct design for a system with an external database and RESTful web gui and service?

Basically, I started designing my project this way:

  • Play! Framework for web gui (using RESTful service)
  • Spray Framework for RESTful service, connects to the database, processes incoming data, serves data for web gui
  • Database. Only the service has access rights to it.

Now I wonder if this is really the best design. Actually with Play! I could easily use both web geeks and a service at the same time. Most likely, it would be easier to test and deploy in simple cases. In complex cases where high performance is required, I can still run one instance only for gui, and several others only to work as services (even if each of them can perform full functionality). On the other hand, I'm not sure if it will hit the performance too much (services will process a lot of data not only from web-gay). Also, isn't this a mix of things that I have to keep separate?

If I decide to leave them separated, will I only be allowed to connect to the database through the RESTful service? How to solve the problem with the service and web gui, trying to use a different version of the database? Should I use a version of the REST protocol in this case?

----------------- EDIT ------------------

My current system structure looks like this:

enter image description here

But I wonder, it makes no sense to simplify it by putting a RESTful service inside Play! gui web server directly.

----------------- EDIT 2 ------------------

Here is a diagram that illustrates my main question. To say this, in other words: would it be bad to connect my service and web gui and share them? And why? Because there are also several advantages:

  • less configuration required between service and gui
  • no data transfer required
  • There is no need to create a separate access level (perhaps this may be a drawback, but in which case?)
  • there are no inconsistencies between the gui / service model (for example, due to different protocol versions)
  • easier to test and deploy
  • no code duplication (usually we need to duplicate most of the model)

However, here is a chart:
enter image description here

+4
source share
3 answers

Well, after several hours of thinking about it, I think I found a solution that will satisfy my needs. The goals I want to accomplish are as follows:

  • Web GUI cannot make direct calls to the database; he needs to use a suitable model, which, in turn, will use the repository of some objects.
  • It should be possible to test and deploy the whole thing as one package with a minimal configuration (at least for the development phase, and then it should be possible to easily switch to a more flexible solution).
  • There should be no duplication of code (i.e. the same code in the service and web gui model)
  • If one approach proves wrong, I need to be able to switch to another

What I forgot to say earlier is that my service will have a built-in cache used for aggregating and processing data, and then commits to the database with large chunks. It is also present on the chart.

My class structure will look like this:

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

So, it looks like a regular MVC web application, except for the fact that there are separate model classes for services and web gui that inherit from the main one.
In Element.scala, I will have an IElementsRepository object introduced using DI (possibly using Guice).
IElementsRepository have two specific implementations:

  • ElementsRepositoryJSON allows you to retrieve data from a service via JSON
  • ElementsRepositoryDB allows you to retrieve data from the local cache and database.

This means that depending on the active DI configuration, both services and web gui can receive data from another service or local / external storage.
Therefore, for early development, I can keep everything in one game! instance and use the direct cache and access to the database (via ElementsRepositoryDB), and then reconfigure the web gui to use JSON (via ElementsRepositoryJSON). It also allows me to run gui and service as separate instances, if I want. I can even configure the service to use other services as data providers (however, at the moment I have no such needs).

More or less, it will look like this:

enter image description here

+1
source

Why do you need a RESTful service to connect to the database? Most games! applications access the database directly from the controllers. Play! The philosophy is considering accessing your models through the service level to be an anti-pattern. The service level can be useful if you intend to share this data with other (non-Play!) Applications or external systems out of your control, but otherwise it is better to keep things simple. But you can also just set the RESTful interface from Play! the application itself for other systems.

Play! is to keep things simple and to avoid the excessive engineering nonsense that has plagued Java development in the past.

+1
source

Well, I think that there is no objective right or wrong answer, but I will offer my opinion: I think that the diagram you provided is exactly right. The RESTful service is the only access point for all clients, including your web interface, and I would say that it should be.

Without saying anything about Play !, Spray or any other web frameworks (or, for that matter, any database servers, HTML template libraries, JSON parsers, etc.), the obvious rule of thumb is to maintain a strict separation of problems while keeping details implementations from leaking into your interfaces. Now you have raised two problems:

  • Performance: The process of marshalling and decoupling objects in JSON views and servicing them via HTTP is quite fast (compared to JAXB, for example) and is well supported by Scala libraries and web frameworks. When you inevitably discover performance bottlenecks in a particular component, you can deal with these bottlenecks.

  • Testing and Deployment: The fact that Play! framework disables servlets, which complicates the situation. I usually suggest for testing / production that you simply take both WAR for your front-end things and WAR for your web service and place them side by side in the same servlet container. For example, I did this in the past using the Maven Cargo plugin . It's not so easy with Play !, but one module that I found (and never used) is the play-cargo module ... Point, do everything you need to make the slots untied, and then glue the bits together for testing but you want to.

Hope this is helpful ...

0
source

Source: https://habr.com/ru/post/1386702/


All Articles