Real-World Project: Choosing a Dependency Stack
Bring together everything from this course by assembling the full dependency stack for a realistic e-commerce order API, plus a decision framework for choosing dependencies on any new project.
Introduction
Over the last 25 lessons, you went through Spring and Spring Boot's dependency landscape one category at a time: web, data, security, validation, testing, actuator, messaging, cloud, documentation, and scheduling. In this final lesson, you will put it all together the way you actually would on a real project — by starting from requirements, not from a shopping list.
The Project: An E-Commerce Order API
Imagine you are starting a new service: an order API for an e-commerce platform. Customers place orders, the API validates and persists them to a relational database, protected endpoints require a logged-in user via JWT, the service exposes interactive docs for the frontend team, and it needs to be observable and well-tested in production.
- Expose REST endpoints for creating and retrieving orders.
- Persist orders to a relational database using JPA.
- Require authentication, with JWT-based stateless sessions.
- Validate incoming order requests before they touch the database.
- Expose health/metrics for monitoring in production.
- Ship with a real automated test suite.
- Provide interactive API docs for the frontend team.
Mapping Requirements to Dependencies
This is the core skill this course has been building: translating a requirement into the specific dependency that satisfies it, rather than adding starters speculatively.
| Requirement | Dependency |
|---|---|
| REST endpoints | spring-boot-starter-web |
| Persist orders relationally | spring-boot-starter-data-jpa |
| SQL database driver | postgresql (runtime driver) |
| JWT-based authentication | spring-boot-starter-security + jjwt (or a similar JWT library) |
| Request validation | spring-boot-starter-validation |
| Health/metrics for monitoring | spring-boot-starter-actuator |
| Automated tests | spring-boot-starter-test |
| Interactive API docs | springdoc-openapi-starter-webmvc-ui |
The Complete pom.xml
Notice that, exactly as covered in the previous lesson, almost none of these need an explicit version — spring-boot-starter-parent handles that for every official starter. Only the database driver, the JWT library, and springdoc (a third-party dependency) need one.
<dependencies> <!-- Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<!-- Data / JPA --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency>
<!-- Security + JWT --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.12.6</version> </dependency>
<!-- Validation --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
<!-- Observability --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
<!-- API Documentation --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.5.0</version> </dependency>
<!-- Testing --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency></dependencies>Click Run to see what this code prints.
A Decision Framework for Any Project
Use this checklist the next time you are tempted to add a dependency, on this project or any other:
- Do I need this right now, or am I speculatively adding it "because we might need it later"?
- Is there a real, current requirement this dependency satisfies — can I point to it?
- Is this an official spring-boot-starter-* (version-managed, well-supported) or a third-party library that needs its own version and its own compatibility checking?
- Does this overlap with something already on the classpath (e.g. adding a second JSON library, or a second logging framework)?
- What does this dependency pull in transitively — have I checked with dependency:tree?
Every dependency you add is code you did not write but are still responsible for: it affects build time, artifact size, startup time, and — most importantly — your exposure to security vulnerabilities in code you never reviewed. Add a dependency because a real requirement calls for it, not because it might be convenient someday.
Avoiding Dependency Bloat
It is tempting, especially after a course like this one, to reach for every starter you now know about. Resist it. A lean, well-understood dependency set is easier to upgrade, easier to audit, and easier for the next developer to reason about than a large one where half the entries are unused "just in case" additions.
- Remove a dependency the moment the feature that needed it is removed.
- Periodically run dependency:tree and ask, for each top-level entry, "what requirement is this here for?"
- Prefer one well-supported library per concern (one JSON library, one logging façade, one HTTP client) rather than several doing overlapping jobs.
- Treat spring-boot-starter-parent's managed version set as a signal — if something is not an official starter, that is a moment to pause and evaluate it more carefully.
Frequently Asked Questions
Generally yes — its overhead is minimal and health/metrics endpoints are valuable even for small services, especially once anything goes into production.
Yes — testing infrastructure costs little to include and pays off the moment the "prototype" survives past its first week, which happens more often than planned.
There is no fixed number, but a good sign of trouble is when you cannot explain, for every dependency, which specific requirement it satisfies.
Key Takeaways from the Course
- Every Spring Boot starter follows the same pattern: add the Maven coordinate, let auto-configuration wire up sensible defaults, then override only what your project needs.
- spring-boot-starter-parent (or the spring-boot-dependencies BOM) is why you almost never specify a version number for an official starter.
- Data access (JPA, JDBC, MongoDB, Redis), security (Security, OAuth2, JWT), and observability (Actuator) each have a dedicated, well-tested starter.
- Cross-service concerns in microservices — config, discovery, gateway routing, declarative clients, messaging — all have first-class Spring Cloud or Spring dependencies rather than requiring hand-rolled infrastructure.
- The right number of dependencies is the smallest set that satisfies your actual, current requirements — not the largest set you know how to configure.
- You mapped a real project's requirements onto a concrete, minimal dependency stack.
- You assembled a complete, coherent pom.xml for an e-commerce order API.
- You have a repeatable decision framework for choosing dependencies on any future project.