A template showcasing best practices for implementing a REST API in Java SpringBoot.
The template showcases building a REST API using the movie industry as the domain. It stores a small set of movie and actor data in an embedded database and integrates with an open movie dataset (TMDB API).
OpenAPI documentation has been enabled via Spring-Docs. On application startup, you can browse the documentation by the following links:
- OpenAPI 3.0 Spec: http://localhost:8080/v3/api-docs
- Swagger UI: http://localhost:8080/swagger-ui/index.html
Note: The dependency implementation 'org.springdoc:springdoc-openapi-ui:1.7.0'
will also support OpenAPI documentation. But it cannot be mixed with the starter dependency.
This template uses clean architecture concepts to define package structure and class dependencies. It's enforced using ArchUnit via a unit test.
This template attempts to use the 12-Factor App guidelines to model a scalable REST API in Java. Those guidelines are:
- One codebase, one application
- Dependency management
- Design, build, release, and run
- Configuration, credentials, and code
- Logs
- Disposability
- Backing services
- Environment parity
- Administrative processes
- Port binding
- Stateless processes
- Concurrency
There is also the 15-Factor App guidelines to be considered, which introduces API First, Telemetry, and Auth/Authz as additional factors.
There are strong opinions on using constructor injection over field injection. Constructor injection is generally considered a better practice for dependency injection, as it makes the dependencies explicit and allows for easier testing and immutability.
For this template, we're using constructor injection by leveraging Lombok's auto constructor generation. We added a config rule telling Lombok to copy desired annotations from the private fields to the constructor on code generation.
The entity relationships defined in this sample project are documented in an ERD diagram.
The integration tests are tests configured to run against a Spring container.
The integration tests are configured in the gradle\integration.gradle
file
and the source is found in src/integration/java
.
The tests run using SpringBoot extensions. They run using either SpringBootTest
or DataJpaTest
.
To execute the integration tests, run the command
./gradlew integrationTest
Wiremock is mocking TMDB API responses for integration tests.
- The stub files can be found in
src/integration/resources/wiremock
. - The test class MovieControllerIntegrationTests configures an in-memory Wiremock server using a JUnit extension.
- Normally, Wiremock looks for stub files in
src/test/resources
but this project has a different directory structure; therefore we've overwritten the default path in the extension.
- Java JDK 17
- SpringBoot
- Spotless - Provides linting to the Java source code.
- JaCoCo - Provides test coverage reporting.
- H2 Database - An in-memory database used for testing and local development.