How can we build microservices inside any project? Because at the end of the day, some great developer has to develop these microservices by using backend languages like Java.
Challenge 1 – How can we build microservices ??
Inside traditional web applications, for example, inside any monolithic web application, we develop all our code with the help of Java classes, methods and we package it as a WAR or EAR file, post that using the same package to file, we can deploy into a web server like Tomcat or any other application servers, and this is going to be a super, super time consuming process.
First, you need to develop a web application. You need to package your application, you need to deploy into your web server. So since this is a time consuming process, do you think this is going to work for building microservices?
Of course not, because inside real time projects, bigger organizations may build hundreds or even thousands of microservices building, packaging and deploying. All these microservices using traditional methods is going to be extremely challenging and it is going to be a practically impossible task. So do you know how to overcome this challenge?
The solution is the Spring Boot framework. With the help of spring boot framework, we are going to overcome all these challenges.
Introduction to Spring Boot Framework ?
Spring Boot framework is the best framework to build Java based microservices.
Why is Spring Boot the Best Framework to Build Microservices ?
Spring Boot is a framework that is built upon the spring framework. It simplifies the development and deployment of Java applications, including microservices.
With Spring Boot, you can build self-contained, executable JAR files instead of the traditional WAR or EAR files. These JAR files contain all the dependencies and configuration required to run the microservice. This approach eliminates the need for external web servers or application servers.
→ With the help of Spring Boot, we can develop and deploy Java based web applications, including microservices, very easily.
It is going to improve the productivity of the developer. It is also going to make the life of developer and platform team and operations team very easy with all the features that it is going to support.
→ With the help of this spring boot framework, we can build self-contained and executable JAR files, instead of traditional war or ear files. Which means you as a developer just focus on your business logic and the framework is going to take care of starting your application and packaging your application and deploying your application into an embedded Tomcat server or into an embedded web server.
So whatever JARs that we are going to generate with the help of this Spring Boot applications, these are self-contained, which means they’re going to have all the dependencies that they require to run the microservices.
→ Spring Boot provides a lot many built-in features and integrations with the help of concepts like Auto configuration, dependency injection, and it also supports various cloud platforms.
Whenever we are using spring boot framework, think like you are trying to create a web application.
As soon as you’re trying to create a web application with Spring boot framework, it is going to make auto configurations to deploy your web application into a web server like Tomcat at a default port of 8080.
So all these kinds of auto configurations, it will try to do by itself by assuming some default values. If you as a developer, if you are not good with those default configurations, you can always override them with the help of properties inside the spring boot framework.
→ Spring Boot framework provides embedded servers like Tomcat Jetty or Undertow, which you can use to run your microservices directly without the need of a separate server, installation and maintenance.
→ Spring Boot framework supports a lot many production ready features, such as providing metrics about your web application, health monitoring and external configurations.
So whenever we are trying to build web applications inside a monolithic approach, we as a developer need to write a lot of code to monitor our web application, to produce metrics from our web application and to configure some external configurations.
Whereas with Spring Boot, everything is going to be super, super easy with the dependencies like spring boot actuator.
→ We can quickly bootstrap a microservice project and start coding with a range of starter dependencies.
Before Spring Boot whenever a developer wants to add a dependency related to some database or some message queues or some other framework, you need to do a lot of configurations inside his project and he needs to add a lot of dependencies manually.
But with the help of starter projects inside Spring Boot, it is going to be super, super easy. You as a developer just tell what dependencies you need inside your web application.
Suppose if I’m trying to connect to a MySQL database, I can define that and my spring boot is going to provide a starter project which will have a bundle of dependencies that will help me to connect with my MySQL database.
Deployment perspective : Traditional v/s Spring Boot
Traditional approach –
To build and deploy monolithic web applications, first we need to have a Java runtime environment like JVM. On top of that, we should also install our web servers like Tomcat, Jetty, Netty, inside our server or inside our laptop.
Once we have these two components ready, then we need to package our applications into war or ear format and we need to deploy them manually into a server.
And with the help of a runtime environment like JVM, our web applications will work where an end user can use them.
Spring Boot approach –
We got rid of this server component because this server component right now is embedded into the JAR of your web application or of your microservice, which means whenever I’m trying to use spring boot to build my microservices, it is automatically going to package my application along with the embedded server.
So as a developer, I don’t need to worry about all the server installations and maintaining all these server configurations.
These self-contained jars were also going to be called fat jars or uber jars because they will have everything packaged, including all the dependencies, all the business logic along with the embedded server.
Implementing REST Services
When I say that we need to build microservices with the help of Spring Boot framework, behind the scenes, we need to implement the REST services.
What is a microservice? It is a service that exposes its business logic to other APIs or to external UI applications with the help of Rest API.
Using REST services, we can establish synchronous communication between multiple APIs or multiple services or multiple web applications.
Synchronous communication means when a request comes from an external application to my microservice, the external application is going to wait for my response so that it can proceed to the next request.
Of course, synchronous communication is not the only option that we have to build microservices, but this is the most commonly used approach.
Definition of REST services
REST (Representational State Transfer) services are one of the most often encountered ways to implement communication between two web apps.
REST offers access to functionality the server exposes through end points that a client can call.
Formally REST service works based upon HTTP protocol.
Compared to soap based web services, REST services are very lightweight in nature because they can work with the help of lightweight data format, which is JSON.
→ Whenever we are building services with the help of REST APIs, our web application is going to expose certain endpoints which my client application can invoke by sending a request.
Different use cases where REST services are being used
- Some mobile apps might be communicating with a backend server with the help of REST API.
- Two different backend servers (or) two different microservices, they can also communicate with each other with the help of REST API.
Standards to follow while Implementing REST services
HTTP Methods
Whenever we are trying to build REST services, we will write a business logic to calculate and to process some data and our REST APIs are going to support CRUD operations on the storage system.
Whenever we are trying to build REST APIs that expose these, create, read, update and delete operations to the external applications, we need to make sure we are following the standards of the Http methods.
– For example, whenever you are trying to save the data or whenever you are trying to create the data with the help of your API, you need to make sure you are accepting the requests with the help of POST method.
– And similarly, if your API supports just reading the data from the storage system and sending the same to the client, then it is just a read operation for such scenarios we should use the GET Http method.
– if your API is supporting an update operation where a client can update the existing data, then we can use the Http method PUT or Http method PATCH.
The difference between PUT and PATCH is if you are trying to update your entire record or major data inside your table record, then you should use PUT.
Whereas if you’re trying to update only a small set of information or a specific column, you should use the Http PATCH method to support the update operation.
→ If the client application wants to delete data inside your application, then you need to expose an API that supports delete operation. And in such scenarios we should use the Http method, which is the DELETE method.
Please make sure you are following these standards whenever you are building REST services and microservices.
Input Validation & Exception Handling
You should perform proper input validation on your REST APIs.
If you consider a UI application, it will have HTML forms, input elements using which you can perform a lot of validations.
But coming to the REST APIs, any application can invoke, it could be a backend application or a mobile application or UI application. So that’s why you should not rely on the validations that are happening in the external system.
You should do your own input validation and accordingly process the request. And after the input validations, we should also take care of exceptional handling.
Regardless if you are getting a runtime exception or a business exception, you should properly handle it and you should always send a meaningful response to the clients. Otherwise you are going to have a very tough time with your clients because they cannot understand what is the issue with your APIs?
Document your REST Services
Always document your services. Inside microservices we are going to build hundreds of REST services and in some cases thousands of REST services. So whenever you are building such a large amount of APIs, it is a good idea or it is a good standard to document your REST services with the help of standards like Openapi specification, swagger.
When you document your REST services well with these standards, your life is going to be easy.
Creating a Spring Boot Project
To get started, we need to come to this website which is start.spring.io.
Inside this website, like you can see, we need to select our project specifications, what language that we want to consider, what is a build tool that we want to consider?
What is the spring boot version?
So all such basic details we need to fill inside this website.
→ The basic requirement for the spring boot 3 version and above is Java 17.
Dependencies to use
Now coming to the dependencies, we need to define what dependencies we need for our microservices. The very first dependency that we need to add is Spring Web.
Since we decided to build REST services, by adding this starter project, my spring boot is going to bring all the dependencies and libraries that I need to build web applications, including REST services, MVC based applications, and it is also going to use Apache Tomcat as a default embedded container.
Since we need some storage supporting databases, now I’m going to go with the H2 database. So H2 database is an internal memory database which you can use inside spring boot web applications. It does not require any installation of MySQL servers or Oracle. You can use this simple internal memory database.
Since we want to connect with a database like H2 database, we need to have a supporting framework. For the same, I want to add the Spring data JPA as a dependency inside my Spring boot web application.
Using this starter projects, we can store the data into the database, we can retrieve the data so all the libraries related to database interaction will be available inside the spring data JPA.
Spring Boot provides inbuilt endpoints to monitor and manage our application, such as health of our application, metrics of the application. Since we are building a microservice and we want to monitor our microservices without writing any external code, I want to use this actuator dependency.
The next dependency is dev tools. So this spring boot dev Tools is a starter project which will improve the productivity of the developer. Whenever we have this dependency inside our spring boot application, it is going to provide fast application restarts, live reload and configurations for enhanced development experience.
Once we start our application, we do some code changes like Java changes, our property changes, in such scenarios, we don’t have to manually restart the server of spring boot by default. Internally, this dev tools is going to restart very quickly by reloading only the changes that I have made.
The next dependency is Lombok. So using Lombok we can avoid all the setters and getter methods that we need to write inside a pojo class. At the end of the day, all the data that we get from UI application or from other applications will
get converted into a pojo class and to access the data from the Pojo class, we will use setter methods. So writing these getter and setter methods is very cumbersome and introduces a lot of boilerplate code. So with the help of Lombok, we can reduce the boilerplate code.
Since we decided to follow the standards of performing validations on the incoming requests, we need to add this Validation starter project inside our spring boot application.
After filling in the details and selecting the required dependencies, I can click on this GENERATE button which will generate a Maven application. This will create a zip file and you download it.
Import Project in IDE
Extract the zip file and load the Maven project into your IDE, either Eclipse or IntelliJ IDE.
Here, this file AccountsApplication, this is the main class inside your spring boot application because it has annotation @SpringBootApplication.
With this annotation, we are telling the spring boot framework to perform auto configurations and to scan all the beans inside our spring boot application.
So @SpringBootApplication annotation is a combination of all these annotations like : enable auto configuration, @SpringBootConfiguration and @ComponentScan.
@SpringBootApplication => @SpringBootConfiguration + @ComponentScan + @EnableAutoConfiguration
@RestController – Creating HelloWorld REST API
Now let’s try to update the above basic spring boot application with a new REST API that gives the response saying Hello World.
In order to create a new basic Rest API, I’m going to create a new package with the name com.eazybytes.accounts.controller.
So inside this controller package I’m going to create a new class. The class name is going to be AccountsController. Inside this class only I’m going to create all the REST APIs related to the accounts microservice.
Let’s try to put an annotation @RestController on top of this class.
Whenever we mention this annotation on top of a class, we are instructing the Spring Boot framework that I am going to write methods inside this class with the annotations related to the Http methods.
Accordingly, please expose all these methods as REST APIs to the outside world. So that is an indication that we are giving to the Spring Boot framework.
Let’s create a method.
So whenever we are mentioning @GetMapping, we are telling the spring boot framework that this method is going to support the Http GET method.
So whoever wants to invoke my API, they need to invoke it with the help of the Http GET method because this method is simply going to return the data to the end user or to the client. That’s why we should use @GetMapping.
Also, since someone wants to invoke this API, we should mention what is the path that this method is going to support.
When you’re trying to do a build very first time, your IDE will ask you to enable annotation processing because it identifies the Lombok inside your classpath. So please enable the annotations so that we can leverage the Lombok Library.
Once the build is completed, Run the application as Spring Boot application. So let’s see the magic that it is going to do behind the scenes.
As you can see here, my accounts application started at the port 8080 and it also identified that I have an H2 database inside my dependency. That’s why it completed all auto configurations related to the H2 console.
The same applies for the actuator. Since we have the actuator related dependency inside our pom.xml spring boot did all the auto configuration and apart from that it is also deployed our web application automatically into your Tomcat server at the port 8080 with the context path empty.
→ Based upon dependencies that I have defined inside my web application, Spring Boot is able to do a lot of auto configuration. It is not asking me to provide what is a port number where it has to deploy, what is the server, where it has to deploy, what are the connection details to my H2 database?
It is not asking all those details and it is assuming and doing some default configurations.
NOTE – we can override these default configurations.
For now, let’s try to access our API with the help of port 8080. For the same inside my browser, I’m going to type localhost:8080 since our application started at the port 8080. And the path that we need to invoke is /sayHello.
localhost:8080/sayHello
Output :