Who this book is for
- What this book is not
- How to read this book
- A note on opinions
- Acknowledgments
Chapter 1: Why Tutorial Knowledge Isn’t Enough
- What tutorials teach you
- What tutorials don’t teach you
- The seven things tutorials skip
- The “real-shaped” project
- The plan
- A request
Chapter 2: Project Overview — Habit Tracker Requirements
- What we’re building
- Why this domain
- User stories
- Out of scope (for now)
- Non-functional requirements
- API surface (preview)
- Data model (preview)
- Why we’re spending a chapter on this
Chapter 3: Designing the Domain and DTOs
- Two layers, one habit
- The domain entities
- Behavior on the entity
- The DTO layer
- Mappers
- Validation: the two layers
- Errors
- Where this leaves us
Chapter 4: Monorepo Structure with Gradle
- What is a monorepo, really?
- The structure we’re building
- Step one: initialize Gradle
- Step two: settings.gradle.kts
- Step three: the version catalog
- Step four: the root build.gradle.kts
- Step five: a platform-lib module
- Step six: another platform-lib module
- Step seven: the actual service
- Step eight: a placeholder application class
- Step nine: try the build
- A note on the
gradle.properties - What we just did
Chapter 5: Implementing the Core Spring Boot Service
- The package layout
- Starting with the DTOs
- The domain entity
- The repository port
- In-memory implementation
- The application service
- The exception
- The mapper layer
- The controller
- The current-user annotation (temporary version)
- Global exception handling
- Wiring up the profile
- Trying it out
- A test
- What we have so far
Chapter 6: Authentication and Authorization with JWT
- What we’re building
- Adding what we need
- The User entity and repository
- The JWT service
- The principal type
- The JWT filter
- The security configuration
- The auth controller
- Updating the @CurrentUserId resolver
- Configuration
- Try it out
- Tests
- What we just did
Chapter 7: Persistence with JPA and Flyway
- Postgres locally
- Adding the persistence dependencies
- The first migration
- Configuring Flyway and the datasource
- JPA entities
- Spring Data JPA repositories
- Completions service and endpoints
- Stats: streaks and completion rate
- Testing with Testcontainers
- What we just did
Chapter 8: Messaging and Events with SQS
- Why SQS?
- The mental model
- The domain event
- The publisher abstraction
- The SQS implementation
- Configuration: which publisher do we use?
- Publishing the event
- The consumer
- Configuration
- Testing event publication
- Where this leaves us
Chapter 9: Dockerizing the Service
- What’s actually in a Spring Boot fat JAR
- Layered JARs
- The Dockerfile
- .dockerignore
- Building the image
- docker-compose for the full local stack
- Image size: where the bytes go
- Tagging and registries
- Smoke test the image
- Where we are
Chapter 10: Deploying to AWS
- What we’re building, architecturally
- Terraform layout
- First deploy
- GitHub Actions
- What I’m leaving out
- Where we are
Chapter 11: Observability
- Spring Boot Actuator: the foundation
- Securing the endpoints
- Custom metrics
- Structured logging
- Correlation IDs and MDC
- CloudWatch Logs Insights queries
- Health checks: liveness vs readiness
- Graceful shutdown
- What about distributed tracing?
- Where we are
Chapter 12: Hardening and Next Steps
- Part 1: Hardening checklist
- Part 2: Feature ideas and what to build next
- Career thoughts
- A final word
Afterword
- Things I changed my mind about while writing
- Thanks