Spring Boot Folder Structure: Best Practices Examples

Spring Boot is a popular framework for building Java-based enterprise applications. One of the key aspects of a successful Spring Boot project is a well-organized and maintainable folder structure. A clean and structured project layout not only makes it easier to navigate and understand the codebase but also enhances collaboration among team members. In this blog post, we’ll explore best practices for organizing your Spring Boot application.

1. Follow the Standard Maven or Gradle Structure

Spring Boot projects are often built using either Maven or Gradle. Stick to the standard directory structure recommended by these build tools. For Maven, the structure typically looks like this:

src
|-- main
|   |-- java
|   |   `-- com
|   |       `-- example
|   |           `-- yourapplication
|   |               `-- Application.java
|   |-- resources
|       |-- static
|       |-- templates
|       `-- application.properties
`-- test
    |-- java
    |   `-- com
    |       `-- example
    |           `-- yourapplication
    |               `-- ApplicationTest.java
    `-- resources
        `-- application-test.properties

For Gradle, the structure is similar:

src
|-- main
|   |-- java
|   |   `-- com
|   |       `-- example
|   |           `-- yourapplication
|   |               `-- Application.java
|   |-- resources
|       |-- static
|       |-- templates
|       `-- application.properties
`-- test
    |-- java
    |   `-- com
    |       `-- example
    |           `-- yourapplication
    |               `-- ApplicationTest.java
    `-- resources
        `-- application-test.properties

Sticking to the standard structure makes it easier for others to understand your project and allows build tools to automatically recognize and configure the project correctly.

2. Package by Feature, Not by Layer

Organize your codebase by feature rather than by technical layers. Instead of having separate packages for controllers, services, repositories, etc., group classes based on the feature they belong to. This makes it easier to locate related components and reduces the need to jump between different layers.

com
|-- example
|   `-- yourapplication
|       |-- feature1
|       |   |-- Feature1Controller.java
|       |   |-- Feature1Service.java
|       |   `-- Feature1Repository.java
|       `-- feature2
|           |-- Feature2Controller.java
|           |-- Feature2Service.java
|           `-- Feature2Repository.java
`-- YourApplication.java

This approach aligns well with the concept of microservices and modularization, making it simpler to manage and scale individual features independently.

3. Utilize the @RestController and @Service Annotations

Spring Boot provides annotations such as @RestController and @Service to mark classes as controllers and services, respectively. Use these annotations to clearly identify the role of each class. For example:

// Controller class
@RestController
@RequestMapping("/api/feature1")
public class Feature1Controller {
    // ...
}

// Service class
@Service
public class Feature1Service {
    // ...
}

This not only improves code readability but also allows Spring to automatically discover and register these components.

4. Separate Configuration Files

Keep configuration files separate from your source code. Place them in the src/main/resources directory. Spring Boot supports various types of configuration files, such as application.properties or application.yml. Use these files to configure application properties, logging, and other settings.

src
|-- main
|   `-- resources
|       |-- application.properties
|       `-- logback.xml
|-- test
    `-- resources
        `-- application-test.properties

Separating configuration files makes it easier to manage different configurations for various environments (development, testing, production).

5. Leverage Spring Boot Modules

Spring Boot allows you to modularize your application using modules or subprojects. Each module can represent a specific functionality or a microservice. This can be particularly beneficial for large projects with multiple teams working on different modules.

my-application
|-- module1
|   |-- src
|       |-- main
|           |-- java
|           |-- resources
|       `-- test
|-- module2
|   |-- src
|       |-- main
|           |-- java
|           |-- resources
|       `-- test
|-- src
|   |-- main
|       |-- java
|       |-- resources
|   `-- test
`-- build.gradle

This modular approach improves maintainability and facilitates independent deployment and testing of modules.

6. Document Your Code

Include meaningful comments, Javadoc, and README files to document your code. This is especially important for larger projects or when collaborating with a team. Documenting your code helps new developers understand the project more quickly and reduces the learning curve.

my-application
|-- src
|   |-- main
|       |-- java
|       |   |-- com
|       |       `-- example
|       |           `-- yourapplication
|       |               |-- feature1
|       |               |   |-- Feature1Controller.java
|       |               |   |-- Feature1Service.java
|       |               |   `-- Feature1Repository.java
|       |               `-- feature2
|       |                   |-- Feature2Controller.java
|       |                   |-- Feature2Service.java
|       |                   `-- Feature2Repository.java
|       `-- resources
|           `-- application.properties
|-- test
|   |-- java
|   |   |-- com
|   |       `-- example
|   |           `-- yourapplication
|   |               |-- feature1
|   |               |   `-- Feature1Test.java
|   |               `-- feature2
|   |                   `-- Feature2Test.java
|   `-- resources
|       `-- application-test.properties
|-- .gitignore
|-- README.md
`-- build.gradle

A well-documented project helps in onboarding new team members, troubleshooting issues, and maintaining the codebase over time.

7. Use Version Control

Adopt a version control system like Git to track changes to your codebase. This allows you to collaborate effectively with your team, revert to previous versions if needed, and manage code changes in a controlled manner.

my-application
|-- src
|   |-- main
|       |-- java
|       `-- resources
|-- test
|   `-- resources
|-- .git
|-- .gitignore
|-- README.md
`-- build.gradle

Integrating version control into your project workflow is crucial for maintaining a stable and collaborative development process.

Conclusion

A well-organized folder structure is essential for the success of any Spring Boot project. By adhering to these best practices, you can create a clean and maintainable codebase that is easy to understand, navigate, and extend. Remember to adapt these guidelines based on the specific needs and requirements of your project, and strive for consistency across your development team