Spring Boot – Code Layout & Structure

Spring Boot and it layout and code structure is something that is not predefined, it is up to the developer to follow the best practices to find the best practices available to them.

You may ask what are these best practices?

What typically occurs is that the project gets divided into layers, for example:

  • Web Layer
    • Controllers
    • Exception handlers
    • Filters
    • View templates
    • Requests and response objects
    • Etc
  • Service Layer
    • Takes data transfer objects (DTOs) as method parameters
      • And basic types
  • Repository Layer
    • Take entities as method parameters
      • And basic types

You can also divide a project into modules…

  • The first module is the data layer
  • The second module is the web layer
  • You can also divide the project into features!

Avoid default package

The default package does not include package declaration, it is not best practice to include a class in the default package.

Why you may ask?

It is because Spring boot scans the classes in the packages and sub-packages in annotations such as:

@SpringBootApplication
@ComponentScan
@EntityScan

And etc.

How about the Main Application Class, where does that go?

It is recommend to allocate the main application class in the root package, this usually has annotations like:

@SpringBootApplication
@ComponentScan
@EnableAutoConfiguration

It enables Spring to scan all classes in the root package and sub-packages. For example, if you are creating a JPA application, the MainApplication.java can be placed in the root package for example:

com.appsdeveloperblog.app.webservice.MainApplication.java

And all Web related classes in the sub-packages (ui) for example:

com.appsdeveloperblog.app.webservice.ui.controller
com.appsdeveloperblog.app.webservice.ui.filters

Service related sub-packages:

com.appsdeveloperblog.app.webservice.services

Repository layer related packages:

com.appsdeveloperblog.app.webservice.repositories

Popular layout structures

There are generally two approach developers gravitate towards on the structure they use for spring, this usually between:

  • Structure by Feature
  • Or.. structure by Layer

You may ask which one is best but this is preferential, below I will outline the benefits between each approach.

Structure by Feature

In this format all the classes are grouped into features, example:

com
 +- appsdeveloperblog
     +- app
         +- MainApplication.java
         |
         +- Student
         |   +- Student.java
         |   +- StudentController.java
         |   +- StudentService.java
         |   +- StudentRepository.java
         |
         +- order
             +- TimeTable.java
             +- TimeTableController.java
             +- TimeTableService.java
             +- TimeTableRepository.java

Benefits of structure by feature

  • ⭐️ Easy searching of classes by feature
  • ⭐️ Easy deletions of features
  • ⭐️ Testing and refactoring is simplified
  • ⭐️ Features can be shipped separately

Structure by Layer

In this approach, all the classes are separated as general layers, i.e. controllers, services, model, dtos, etc…

com
 +- appsdeveloperblog
     +- app
         +- MainApplication.java
         |
         +- domain
         |   +- Student.java
         |   +- TimeTable.java
         |
         +- controllers
         |     +- StudentController.java
         |     +- TimeTableController.java
         |
         +- services
         |    +- StudentService.java
         |    +- TimeTableService.java
         |
         +- repositories
              +- StudentRepository.java
              +- TimeTableRepository.java   

Although the structure by layer appears easy to locate classes, it does have disadvantages compared to structure by feature.👎

  • ❌ Features and modules cannot be shipped separately
  • ❌ Searching for classes that have a certain feature is harder
  • ❌ Refactoring on a certain feature is difficult, as the feature is located on every layer!
  • ❌ Can cause merge conflicts

Final note

To note, either approach can be feasible, you may find the structure by layer a good approach even with the highlighted down sides. For instance, if the spring boot application itself is dedicated to one specific feature, and you plan to separate these out into separate spring boot applications, this would negate the downsides, which in turn also has the added benefit of deploying individual micro-services per spring boot project.

Leave a comment