Basic Spring Boot Project Architecture

Table of contents

No heading

No headings in the article.

Spring boot is a java-based framework that has been introduced in 2014 as part of the Spring framework eco-system. It is designed to quickly develop and deliver production-grade applications. It introduced many features like auto-configuration, embedded Tomcat and the layer of abstraction that reduces the amount of boilerplate code. It is very easy to learn and get used to for both beginners and experienced java developers.

In this article, we're going to have a brief look at a simple Spring Boot application to give you some idea of how easy it is to start developing an application as quickly and painlessly as possible.

To start, let's list down the common components of a Spring Boot project such as the one we'll be working on. A Spring Boot project is usually divided into modules or layers as follows:

  • The controller layer

  • The service layer

  • the repository or Data Access Layer

  • The model or domain layer

  • The configuration layer

Let's talk more about each layer:

  • The controller

    The controller is a java class where we define our APIs. It is the first point of contact with the client where it's responsible for handling HTTP requests (GET, POST, PUT, DELETE). If the client sends a get request to fetch some resource from the database, the controller will send that request to the service layer, which sends it to the data access layer to fetch it from the database.

  • The service

    This is where we define our business logic. This class transfers requests and data between the controller and DAO layer and performs operations, if required, on those data.

  • The DAO or repository

    The DAO or Data Access Object is an interface responsible for persisting and retrieving data from the database based on the type of request received from the service layer. When Spring Data JPA is integrated into a Spring Boot project, our DAO interface can extend one of Spring Data JPA's interfaces which contains a number of common useful database operations like create, retrieve, update and delete. Examples of those repositories include JPARepository, CrudRepository and PagingAndSortingRepository.

  • The model/ domain layer

    Models are java objects that represent the data transferred between the application and the client. We can map a model to a table in a relational database typically using an ORM tool like Hibernate where each property of the model corresponds to a column of that table. In the context of relational mapping, we can refer to the model class as an entity.

  • The configuration layer

    Spring Boot provides different ways to define configuration settings for database, security and any configuration required to set up an application. The most common ways are using application.properties or application.yaml file and Java configuration classes

Now let's create these classes and their packages step by step.

  1. First, We'll start with the application.properties file, which is provided by Spring Boot by default in the /src/main/resources directory. We'll declare database properties to connect to postgresql database as bellow. You can use any database of your choice.

     spring.datasource.driverClassName=org.postgresql.Driver
     spring.datasource.url=jdbc:postgresql://localhost:5432/user
     spring.datasource.username=postgres
     spring.datasource.password=postgres
    
    • As you can see above, we declared the database Driver, url, username and password.

    • Now once we run the application, it will connect to postgres with these credentials.

  2. Next, create the following packages under src/main/java: controller, service, repository and model or entity

  3. Now we can start with the model. Inside the /model or /entity package, create a class and call it User and define your fields, constructors, getters and setters. If you're using Spring Data JPA, you may add the relevant annotations

     @Entity
     @Table(name = "user")
     public class User {
         @Id
         private Integer id;  
         private String userName;
         private String password;
         // constructors
         // getters and setters
    
    • @Entity and @Table denote the object that will be mapped to the respective database table.

    • @Id is used on top of the id field that represents the primary key of the entity.

  4. As a next step, let's create the DAO layer, which will be an interface inside the /repository package and will extend JpaRepository provided by Spring Data JPA.

     @Repository
     public class UserRepository extends JpaRepository<User, Integer> {
     }
    
    • @Repository is a specialized form of Spring's @Component annotation to denote the repository.

    • Notice that JpaRepository has two parameters: Entity type and primary key type of that entity

  5. Next, we'll create a service class inside the /service package and then autowire our UserRepository and define some methods that invoke methods from that repository.

     @Service
     public public UserService {
    
         @Autowired
         private UserRepository userRepository;
    
         public List<User> findUsers() {
             return userRepository.findAll();
         }
    
         public User findUserById(Integer id) {
             return userRepository.findById(id).orElse(null);
         }
    
         public User saveUser(User user) {
             return userRepository.save(user);
         }
    
         public User updateUserById(Integer id, User user) {
             User updatedUser = userRepository.findById(id).orElse(null);
             updatedUser.save(user);
             return updatedUser;
         }
    
         public void deleteUserById(Integer id) {
             User user = userRepository.findById(id).orElse(null);
             userRepository.delete(user);
         }
     }
    
  6. Lastly, let's create a controller class inside the /controller package.

     @RestController
     @RequiredMapping("/user")
     public class UserRestController {
    
         @Autowired
         private UserService userService;
    
         @GetMapping
         public List<User> getUsers() {
             return userService.findUsers();
         }
    
         @GetMapping("/{id}")
         public User getUserById(@PathVariable Integer id) {
             return userService.findUserById(id);
         }
    
         @PostMapping
         public User postUser(@RequestBody User user) {
             return userService.saveUser(user);
         }
    
         @PutMapping("/{id}")
         public User putUser(@PathVariable Integer id, @RequestBody User user) {
             return userService.updateUserById(id, user);
         }
    
         @DeleteMapping(/"{id}")
         public String deleteUser(@PathVariable Integer id) {
             userService.deleteUser(id);
             return "user has been deleted successfully";
         }
     }
    
    • The @RestController annotation indicates this class will be handling web requests

    • Here, we're injecting our UserService into the controller and creating API methods that invoke each service method.

    • All @GetMapping, @PostMapping, @DeleteMapping and @PutMapping annotations are used to map HTTP requests to the appropriate handler methods.

    • @PathVariable is used to bind a method parameter to the path variable. In the GET request in our example, the id passed in the url will be extracted and passed to the method as a parameter to query the database for a record with that id.

    • @RequestBody binds the JSON payload or request body of an HTTP request to a method argument, which is usually a java object.

Once you run the application, you can use a tool like postman to test each request using the proper endpoints. The endpoint of POST request would be http://localhost:8080/user and the JSON request will look something like this

{
    "id": 1,
    "userName": "user",
    "password": "test@123"
}

Once you send the above request, a record should be saved to the database. To fetch that record, you can send a request using the same url but as a GET request.

You can learn more about Spring Boot in detail by going through Spring's guide here https://spring.io/guides/gs/spring-boot/
or Baeldung's blogs here https://www.baeldung.com/spring-boot