When Monolithic Is the Way: Play vs. Spring Boot vs. Grails
This article reviews the benefits of using a monolithic structure for your project, and choosing which framework to use based on features and documentation.
Join the DZone community and get the full member experience.
Join For FreeNowadays, when we are going to start a new project, the developer starts thinking about the technology, and usually they come up with something like: microservices, RESTFul, Actor model, NoSQL, single web app, and so on.
All of those are fantastic concepts that must be taken into account when defining a new architecture and technology stack. However, I strongly believe that when the resources (time, money, and developers) are limited and/or there are strong timing constraints, a monolithic solution is the only way to succeed.
With a monolithic application and the right framework, all technical resources can be focused on the business logic implementation, and it is possible to deploy it in almost every type of SaaS or PaaS now on the market.
The Options
As a Java developer, I can only think of the following options:
There are plenty of other options, but I think these three are the most famous, well-documented, well-known, and stable.
If you're not a Java developer? Well, Play can be used with Scala and Grails uses Groovy as the main language, which is very similar to Python, and Spring Boot can be used with both Java and Kotlin. However, if you are not confident with any of these languages, you can continue reading this article, skipping the details about the specific framework and focusing on the main concepts which are fundamentals to evaluate a good framework.
The Metrics
Choosing a technology is usually very difficult- there are plenty of new technologies that come out every year, and they are all valid, so how can we identify the most appropriate one? I think the most important aspects are:
Structure and Features
Resources
Performance
There are also other aspects that must be evaluated, which I cannot evaluate in an article because they are not strictly related to the framework itself: the team knowledge/experience and the average usage of that technology in your country (when new developers will be needed, it is better to look for skills that are quite common).
The Evaluation
In order to evaluate this three technologies, I have built a really simple web app which displays the Berlin Clock (Mengenlehreuhr). I have decided to build it in single web app style, so, a static HTML page which contains the page structure, and JavaScript code that consumes a REST API and adjusts the page content according to the data received.
All implementation have the same static HTML, JS, and CSS code, the only difference is how the API and routes are defined.
You can find all the code here; the implementation is very easy and can be rewritten in a smart way, so please "do not look at the finger which is pointing at the moon."
Structure and Features
All of them define well-separated layers for the presentation and the business logic, however, they implement quite different solutions:
Routing Layer
Both Play and Grails have a specific file which contains only the routing information (URL and action). It is usually one, but you are able to create more, whereas the routing in Spring Boot is different; it is defined by annotations in each controllers' methods.
I personally like the idea to have a specific file, because, when your API layer will become big, it will be difficult handle it if its definition is spread around the code, on the other hand, have the route defined into the controller helps the readability in case of small projects.
It is also possible to easily integrate tools for automatic API documentation in all frameworks; I personally tried Swagger.
It has been extremely easy configure it in Spring boot thanks to the libraries “springfox-swagger2” and “springfox-swagger-ui”; a bit longer and with more code necessary for both Play and Grails (I think mostly because of their routing layer).
It may be unimportant at the beginning, but it will help a lot in the case of future product evolution and migration.
Serving Files
All of them provide a way to serve files both static and compiled on the server side. Nowadays, I think the single web page is a very good approach to the web, so it should be easy provide static HTML, JavaScript, and CSS files. Indeed, it is extremely easy to serve a static file from all of them.
Play and Grails need a specific entry in the route/URL mapping file, whereas Spring Boot assigns a default URL for each file present in the public folder, and the one with name “index.html” will serve as the default for the route path.
In this case, I prefer the Play and Grails approach because it gives me more control. If I want to change the URL that serves a specific file in Spring Boot, the only way I have found is to create a controller class.
Coding
When a new technology comes out, the first thing you get is the famous and deathless “Hello world” implementation, usually built with a couple lines of code. To be honest, I don’t know why this is so important. For me, what actually matters is how much time and code are necessary to build a base production case, like an API which returns a JSON provided by a service; in other words, a model class, a controller, and a service.
In this scenario, Grails is the easiest one, with its massive “convention over configuration,” a built-in JSON converter, and a DI (dependencies injection) name based, you really need a couple of lines of code to create an API that provides JSON.
Spring Boot makes it easy as well- you can just define the model as standard POJO class, use the “@RestController” annotation to define the controller and the standard “@Inject” annotation in order to define the components to be injected, and you are ready to go.
Play provides built-in JSON conversion, but, for the DI, it is necessary to import an external library; I have used Guice, which has very similar usage to the Spring annotation but it requires a module (Scala/Java class) which links the component interface with the actual implementation.
I definitely prefer the Grails approach. No code at all should be necessary for this kind of things, however, it could be tricky for someone who has never worked with Grails keep all the conventions in mind.
Testing
This is the first thing left behind when time is against the developer. Because of that, it must be extremely easy to write tests.
Thanks to the TDD philosophy that now is known to every developer (and I hope is used, too), all frameworks provide a valid solution for testing. By default, Spring Boot provides a solution based on JUnit, Grails based on Spook, and Play on ScalaTest (and JUnit for Java).
I didn’t have any issue or difficulty with any of them, however, with ScalaTest and Spock, it is possible to implement the test in BDD style, which can be an advantage because you can document your code very well (as for TDD vs BDD, is just a personal point of view that with BDD tests' style, I can understand what the functionality does just by reading the test method name).
Server Reload at Runtime
This is a must- without it, you will lose precious seconds and the little calm you still have left. Grails has a built-in system which is very efficient, it recompiles the modified class and that’s it without restart the whole app.
Spring Boot does not have it by default, but it is possible to add “spring-boot-devtools” as a dependency and it will restart the whole application every time there is a change in the classpath.
Play has a built-in system for the automatic reload, but it reloads the whole app every time there is a change.
I think Grails is a bit more reactive than the others because it usually does not need to reboot the whole application, but there is no real big difference here.
Resources
The most important aspects of the resources are the official documentation and the community. I don’t like to buy a book specifically for the technology I’m going to use; the official documentation and tutorial must be enough. Also, when there is a problem I have never faced and I don’t fully understand, I ask “Saint Google” and hopefully get the response.
So, what about our three frameworks? Long story short, Spring Boot is the winner, you will find a lot of official and nonofficial tutorials, a lot of questions and answers in StackOverflow, and more than good official documentation.
Grails has a long history, so you will find a good amount of tutorials (unofficial) and answers on StackOverflow; the official documentation is good, but be careful to choose the right version.
Play has good overall documentation and official tutorials, but some advanced aspects are not well covered.
As a general idea, I prefer not to use the latest released versions because it will be difficult get some help and they can have bugs that have not been discovered yet.
Performance
I don’t think the specific performance of a framework is extremely important, however, it may save resources (and cost) and will give you “more time” for an eventual migration to other architectures (i.e. microservices).
I have executed performance tests with Apache JMeter 3.3 on Windows 7 with
Processor: 2,5 GHz Intel Core i5
Memory: 8 GB 1600 MHz DDR3
512GB SSD disk
The test has been executed with 50 threads executing 300 requests each in parallel. All applications have been executed with their embedded web servers.
These are the aggregate data provided by JMeter:
Framework |
Samples |
Average |
Min |
Max |
Std. Dev. |
Error |
Throughput |
Received KB/sec |
Sent KB/sec |
Avg. Bytes |
Spring |
15000 |
34 |
0 |
5382 |
246.94 |
0.0% |
997.9/sec |
348.38 |
130.59 |
357.6 |
Grails |
15000 |
44 |
0 |
6115 |
274.11 |
0.0% |
931.7/sec |
373.60 |
121.92 |
410.6 |
Play Java |
15000 |
77 |
0 |
3386 |
325.61 |
0.0% |
603.0/sec |
344.31 |
78.91 |
584.7 |
Play Scala |
15000 |
58 |
0 |
3056 |
238.45 |
0.0% |
694.2/sec |
396.52 |
90.84 |
584.9 |
As you can see, Spring Boot and Grails perform very well, much more than Play with its fully asynchronous model. This is something that really surprised me.
Play and Scala are known to be quite responsive, and they are, but on well-configured servers (preferably Linux). Unfortunately, I wasn't able to execute tests on a like-production server, but the web is full of performance tests.
As you can see, there is no significant difference between Grails and Spring Boot because they share the same base technology, the Spring suite.
Something Else to Take Into Account
What’s left? We can evaluate the available libraries or test frameworks, but thankfully, all those frameworks are JVM-based, so it is possible to use all libraries that have been built in Java. However, despite its possibility to use Java libraries, Play with Scala can make life difficult due to the different types between Scala and Java.
Another aspect is the IDE support. There are good options for all frameworks; both Eclipse and IntelliJ IDE can be used with that framework, though the community version of IntelliJ IDEA does not have support for Grails and it could be quite challenging to use it. As a general view, Spring Boot has the best IDE support, followed by Play; Groovy definitely has the worst support (except if you want to buy the IntelliJ IDE Ultimate edition).
Conclusion
I had the opportunity to work with all of these frameworks in a professional environment and I really like all of them- they have different approaches to solve the same problem and they are all valid, but a choice needs to be made.
Looking at the data I have collected, Spring Boot is the one with a good overall result in all aspects. Grails is the best option if the time is really limited because with the massive convention over configuration, you have only to focus on the business logic implementation, and it is extremely simple to bootstrap a complete web application. Play is a good option for Scala developers, and its actor model base system can help with specific applications which require a fast scaling system.
From my personal point of view, I choose the technology which gives me more confidence. When I have a bug (especially on Friday evening), I do not want to spend days searching Google or debugging to try to understand why the framework is throwing that exception.
The key point here is, please do not start a new project with super cool architectures if they are not really necessary (and usually they are not). A standard monolithic web application can run a successful business for a long time- just look at all big companies like Amazon, Netflix, Twitter, and so on. Keep it simple! That's the base rule.
Is monolithic the only alternative? Definitely not. There is another architecture which can fulfill this segment- the Serverless architecture. I’d like to spend more time studying and trying it, however, keep in mind that a future migration to in-house solutions or different architectures could be very tricky.
Opinions expressed by DZone contributors are their own.
Comments