There are many prejudices regarding Java. And I have to admit that I too had these when I learned Java at the university. Java seems to be full of boilerplate code and weird conventions. It simply felt uncomfortable developing in Java when you came from Python. But Spring Boot or the Spring ecosystem, in general, does a great job of modernizing Java.
This is a rather practical post. If you’re just interested in the code, though, that’s fine too. You’ll find all the files on GitHub: https://github.com/code-specialist/spring-boot-api.
What’s Spring Boot?
Spring Boot is a part of the Spring ecosystem, which targets to enable modern and fast Java development. Spring itself belongs to Pivotal, a company specializing in cloud development and consulting, belonging to VMWare since 2019. The Spring ecosystem consists of dozens of technologies such as Spring Cloud, Spring Data, and Spring Web Services, to name a few. In fact, spring.io currently lists 23 technologies.
Spring Boot significantly reduces the time spent on design and development by defining and assuming various things by default. It is an opinionated framework, meaning decisions implicitly occur if the developer doesn’t explicitly define them differently. At first, this might sound like a weakness, but things work out by specifying default values, frameworks, and processes. These decisions are also not binding. Developers and architects may choose their options are they wish and overwrite the implicit defaults explicitly if necessary.
Often, developers reach the same conclusions regarding framework and library choices. As a result, Spring offers so-called “starters”, which contain bundled technology and framework choices, to reduce further the effort spent selecting technologies. This again is a characteristic of its opinionated nature. The “spring-boot-starter-web” for example, bundles Spring MVC and Tomcat as the default embedded container to ease the way RESTful web services are implemented.
Spring is a very mature open source solution. It consists of 210 Repositories and 39 people designated to manage the contributions. Spring Boot, for instance, currently has about 57k GitHub stars. All this allows the development of common architectural patterns such as REST or RESTful APIs, Web Services, and Microservices in Java in a concise time scale. But even more important: without sacrificing any quality attributes such as testability, stability, scalability, or security, as you may be sure, all the things built into Spring are well tested in various production scenarios.
Spring Boot Key Properties
Some of the key properties were already mentioned, but we want to wrap them up again to understand what Spring Boot stands for.
Fast and Flexible
Because it is opinionated, many options and configurations are made implicitly, setting up applications is insanely fast. Though, there is nearly no loss of flexibility as all those implicit choices may be revised explicitly. This leads to less time spent on architecture and implementation as many decisions are assumed and often meet the criteria. It is also easy to extend as the whole Spring ecosystem uses the dependency injection principle widely.
Secure and well tested
Spring has been on the market for nearly 20 years and has seen various iterations, versions, and productive applications. There are lots of contributors (832 on 3rd September 2021) and about 22k closed issues. Not only do you get free support quickly because any problem you could run into is listed somewhere on Stack Overflow, but also the chance that potential weaknesses are still in the code is considerably low. Additionally, it is easy to use mocks and write unit or integration tests because of the dependency injection principle.
Spring Boot Advantages and Disadvantages
Before we jump straight into a practical example of Spring Boot, we want to look at the advantages and disadvantages of Spring Boot. Please note that this is my personal view. It may not be yours or anyone else’s.
In conclusion, I have to note that I got surprised pleasantly. I would definitely reuse it for a fitting case. But if you have not used Spring Boot yet, wait until you have read the practical part and come to your conclusion.
Building a RESTful API with Spring Boot
To follow this documented practical example, we suggest you have basic programming and Java experience and a basic understanding of web services and REST concepts. This is not a deep dive but an overview with practical relevance.
You may skip parts or jump right into the code in the repository.
API Idea and Data Model
Our project at hand should model two entities. Persons and Skills. The API may have an indefinite amount of people and skills. People can have an indefinite amount of skills. To model this many-to-many relation, we need an additional table that maps this. This should be common knowledge to you, but depicting these relations makes understanding the following steps considerably easier.
As a database, we will use PostgreSQL, but you may use whatever database you prefer. To do so, we use the latest official PostgreSQL Docker image with Docker Compose. Your configuration may look like this:
To launch this setup, simply install Docker and Docker Compose and run
docker-compose -f postgresql-compose.yml up -d
Whereas postgresql-compose.yml represents your local configuration in the current working directory. This will deploy a PostgreSQL Database available on Port 5432 of your local machine. The credentials will be set as given in the environment section of the config file.
New Spring Boot Project with Initializr
To initialize a Spring Boot project, you may use the initialzr. If you use IntelliJ, you may also use the IDE directly to create a new project. In this example, we use the initializer so anyone can follow the preceding steps. We leave everything as suggested by the tool and only adjust the group, artifact, and description as desired, and last but not least, add Spring Web as a dependency. Finally, you can download the generated files and jump right into your code.
In the following code examples, you might wonder what those @Getter and @Setter annotations are. These belong to the Lombok Project. Lombok is a library that enables you to negate a downside of Java: Boilerplate code. By annotating the classes with @Getter or @Setter, Lombok generates the setter and getter functions for you. The library also provides functionalities such as @NoArgsConstructor (which should be self-explaining?) and many more. This tutorial’s focus can’t be to provide deep insight into Lombok. To add Lombok to your project add the maven dependency:
This step, however, is optional. If you do not want to use Lombok you can use your own setter and getter functions or generate them with your IDE of choice.
Data Model Implementation
In order for the Object Relational Mapper (ORM), and the Java Persistence API (JPA) to work properly, we need a Java representation of the entities. As you see in the API Idea and Data Model we need at least 3 classes: Person, Skill, and PersonSkills. Additionally, we will create a class for the natural key of the PersonSkills class we name PersonSkillsKey. First, we set up the Person class as follows:
We do the same thing for the Skill class:
The definitions slightly differ, as we do not specify the person in the skill. This means the relationship is not set up bidirectional. Next, we need to define the class that maps these two tables via person_skills.
As we usually create a PersonSkill with a person and a skill we need such a constructor for later. We also have to implement a class that is serializable in order to have a natural key for the table:
We deconstruct the many-to-many relationships into two many-to-one relationships by creating the PersonSkillsKey class. This is common practice to reduce the complexity of models and eases the way the models can be handled.
To connect our newly created Spring Boot Application to our database we need to add the PostgreSQL dependency to our project by adding it to the
Then we need to configure our connection. We in this case use an
application.yaml file, because it is way easier to read than the common properties file. The file is located in
We also enable the ddl-auto feature with the update strategy, letting the hibernate ORM create the data model we defined earlier as required.
Caution: Using the wrong strategy here in productive cases may lead to data loss. Check the documentation to identify the correct strategy for your case.
Finally, we add some test data to the database by writing some simple lines in SQL, for instance:
To connect to the SQL console of your PostgreSQL Docker Container, you may use:
docker exec -it skill-api-postgres psql -U pg-user
Next, we create repositories for our entities. Repositories are, in simple terms, a kind of CRUD API for our data model. We utilize it by using the JpaRepository class:
Each entity needs such a repository. For more information on the repositories and the methods they expose, check out the Spring Documentation.
To map the methods we created using the repositories, we need a controller that connects web requests to our application logic. In this example, we’re going to create a controller for the person entity. To do so, we create a RestController with a RequestMapping to “/person”:
The Autowired annotation cares about all the links between the repositories and our controller. The Get, Post, Put, and Delete mappings relate directly to the HTTP verbs called on the corresponding endpoints. This RestController does not implement all the functions we usually expect from entities, but you should be able to build most of them by yourself now. To document and play with these endpoints to verify it works, we’re going to use Springdoc.
API Documentation with Swagger UI via Springdoc [OPTIONAL]
To add Springdoc and enable the Swagger UI, again, all you have to do is adding the dependency to the pom.xml:
When we add this dependency to our application, a swagger UI will be locally available at http://localhost:8080/swagger-ui.html displaying the methods we exposed with our REST controller:
Of course, you may use any other tool such as Postman or the Insomnia REST Client to test your endpoints. If you configured everything as described, you should be able to try the endpoints as well. For example, a GET request (you can use your browser as this is the default HTTP verb of your browser) to http://localhost:8080/person should return:
Creating data models and exposing their CRUD API with Spring Boot is hilariously easy and effective. The Spring ecosystem is not only well tested but also easy to set up. This is due to an almost perfect balance of default settings and the possibility of controlling them.
My learning about Spring Boot was: Do yourself a favor and be more open-minded towards technologies and frameworks. As you do with people, you should judge first if you were able to experience it and then form your own opinion. Each technology has its specific advantages and disadvantages. Whether a technology is good therefore depends irrevocably on the specific use case.
I am a computer scientist and entrepreneur from Germany. I chose to work in computer science because I love building things and improve people’s lives.