The first five chapters cover bootstrapping a Spring Boot application, building REST controllers with @RestController, request mapping and data binding, Spring Data JPA repositories, and integrating a database. These chapters give you everything needed to build a real CRUD API from scratch.
Scaffold the Task Board monolith with Spring Initializr (Spring Web, Spring Data JPA, H2 or PostgreSQL, Lombok). Implement two entities — Project and Task — with a one-to-many relationship. Expose full CRUD REST endpoints for both. Use Spring Data JPA repositories — do not write any raw SQL. Validate inputs with @Valid and return structured error responses. Commit with a clean package structure: controller, service, repository, entity, dto.
Robert C. Martin's definitive talk on the five SOLID principles with diagrams and Java-adjacent examples. Watch it once to understand the vocabulary, then re-watch with your Sprint 1 code open and identify violations as he explains each principle. Free, ~1.5h.
Review the service classes from the Spring Framework task. Identify every Single Responsibility violation: classes that handle both business logic and persistence decisions, methods that do more than one thing. Refactor them — one service class per entity domain, each method with a single, name-revealing purpose. Then find one place to apply the Open/Closed Principle: introduce an interface or abstraction that lets you add new task filtering strategies without modifying existing code. Commit with a message naming each SOLID principle addressed.
Fowler's article defines microservices clearly and objectively — including when they are and are not appropriate. Read this before any decomposition work. It provides an honest framing of trade-offs that prevents the most common mistake: jumping to services before the monolith is clean. Free, ~30 min.
Sam Newman's first two chapters extend Fowler's definition, introduce the trade-offs, and describe the organisational context microservices come from. Read these after the Fowler article — they extend, not repeat, it.
Write ARCHITECTURE.md in the repo. Include: a component diagram of the current monolith (entities, services, repositories, controllers), the data flow for creating a task, and a section titled "Future Service Boundaries" where you identify exactly 3 places you would draw a service boundary and why. Use Fowler's vocabulary: bounded context, single responsibility at the service level, cohesion. This document will be updated in sprints 2 and 3 — do not delete it, only evolve it.
Chapter 9 covers Spring Security's filter chain, authentication providers, and configuration. It gives you the architectural understanding of how Spring Security works — which is what you need before wiring JWT into it.
Baeldung's guide walks through the complete JWT filter implementation with Spring Security 6's lambda DSL — the piece the book does not cover directly. Free, kept up to date with each Spring Security major release.
Add user registration and login endpoints that issue JWT tokens. Protect all Task and Project endpoints so only authenticated users can access them. Use a JwtAuthenticationFilter that reads the Authorization: Bearer <token> header. Then write JUnit 5 unit tests for every method in your service classes using Mockito to mock the repositories. Target: above 70% line coverage on the service layer. Run ./mvnw test and commit the passing test run output in the PR description.
Robert C. Martin's book applies SOLID at the architectural level — across layers and modules, not just inside classes. Chapters 1–7 cover the foundational argument (why architecture matters) then map directly to the five SOLID principles as architectural constraints. Reading them after a month of Spring code makes the examples concrete.
Review every place in the Task Board where a high-level module (service) directly instantiates or references a low-level module (repository, external service). Refactor to inject dependencies via constructor injection using interfaces. Every service class should depend only on an interface, never on a concrete implementation. Add a diagram to ARCHITECTURE.md showing the dependency flow — controllers → service interfaces → implementations → repositories — making it visually clear that dependency arrows point inward.
Chapter 3 covers finding service boundaries using Domain-Driven Design. Chapter 4 covers integration patterns for service communication. Chapter 5 covers splitting a monolith. These three chapters are the core of Newman's book — read them with your Task Board architecture in mind.
Define the API contracts for your three planned services (user-service, task-service, notification-service) as OpenAPI 3 YAML specs — even though the services do not exist yet. Each spec should define the endpoints, request/response schemas, and authentication requirements. Commit all three specs under docs/openapi/. Update ARCHITECTURE.md with a bounded context diagram showing each service, its data ownership, and the events or API calls that cross boundaries. From this point forward, any contract change must update the spec first.
Chapter 13 covers Spring Cloud Config Server for centralised configuration management. Chapter 14 covers Feign declarative HTTP clients for service-to-service communication — reducing inter-service HTTP calls to a single annotated interface.
Official Spring Cloud Gateway guide covering route configuration, filters, and load balancing. More current than the book for gateway setup with Spring Boot 3. Free.
Extract the monolith into three independent Spring Boot applications: user-service (registration, login, JWT issuance), task-service (projects, tasks, assignments — calls user-service via Feign to validate tokens), and notification-service (consumes task-assigned events from RabbitMQ and logs notifications). Add a config-server Spring Boot app that serves application properties from a local Git repo. Each service must load its config from the config server at startup. Document the startup order in README.md.
Chapter 22 is the centrepiece of the book: the concentric-circle diagram separating entities, use cases, interface adapters, and frameworks. Supplement with Cockburn's original "Hexagonal Architecture" article — the ports-and-adapters pattern is how this clean architecture is implemented in practice.
Refactor task-service to follow the ports-and-adapters pattern: the domain model and use-case classes in a domain package must have zero Spring or JPA imports. Persistence is an adapter behind a TaskRepository port interface. The REST controller is an adapter behind an inbound port interface. The Feign client to user-service is an adapter behind an outbound port interface. Draw the updated architecture diagram and add it to ARCHITECTURE.md. Confirm the domain package compiles cleanly without Spring on the classpath — this is the only reliable test for genuine hexagonal architecture.
Chris Richardson's book is the most practical microservices text available. Chapter 1 defines the patterns vocabulary. Chapter 2 covers decomposition strategies. Chapter 3 covers inter-process communication (REST vs async messaging). Chapter 4 introduces the Saga pattern for distributed data management.
Official Docker tutorial covering Dockerfile syntax, layer caching, volumes, and Docker Compose. Deliberately short — delivers the mechanical fluency needed for the Sprint 3 containerisation task in under 2 hours. Free.
Write a Dockerfile for each service (user-service, task-service, notification-service, config-server). Write a docker-compose.yml at the root that starts all services plus a PostgreSQL container and a RabbitMQ container. Add a Spring Cloud Gateway service as the single entry point — route /api/users/** to user-service and /api/tasks/** to task-service. Confirm the full system starts with a single "docker-compose up" from a clean machine. Update README.md with the architecture diagram, the startup command, and example curl requests for the main flows. Tag the release on GitHub as v1.0.0-ms.