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?
![](https://scalablehuman.com/wp-content/uploads/2022/10/gandelf-meme-1.jpg?w=500)
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
- Takes data transfer objects (DTOs) as method parameters
- Repository Layer
- Take entities as method parameters
- And basic types
- Take entities as method parameters
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
![](https://scalablehuman.com/wp-content/uploads/2022/10/meme-1.jpeg?w=500)
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.