How I Built a Microservices App With Spring Boot (And What Broke Along the Way)

September 15, 2024

How I Built a Microservices App With Spring Boot (And What Broke Along the Way)

When I started the Lumora project during my Capgemini training, I thought microservices would be straightforward.

Spoiler: They were not.

The Idea

A car wash booking platform where:

  • Customers book services
  • Payments are processed via Stripe
  • Admins manage bookings and users
  • Everything communicates through an API Gateway

Simple enough, right? Wrong.

The Architecture (That I Redesigned Three Times)

My first attempt had everything in one Spring Boot app. My mentor looked at it and said: "This is a monolith. We're building microservices."

Back to the drawing board.

Final architecture:

ServiceResponsibility
user-serviceAuth, registration, JWT
booking-serviceCreate/manage bookings
payment-serviceStripe integration
notification-serviceEmail on booking + password reset
api-gatewayRoutes all traffic
config-serverCentral configuration
eureka-serverService discovery

The Part That Broke Everything: JWT + API Gateway

I had each service validate JWT tokens independently. This meant:

  • Every service imported the same JWT library
  • Token secret was duplicated across config files
  • One typo = authentication fails silently

Fix: Moved JWT validation to the API Gateway only. Services trust the gateway. One source of truth.

// Gateway filter - validate once, forward with user info @Component public class AuthFilter implements GlobalFilter { public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String token = exchange.getRequest().getHeaders().getFirst("Authorization"); // validate and attach user context return chain.filter(exchange); } }

Stripe Integration — Easier Than I Expected

I was terrified of payment integration. Turned out Stripe's Java SDK is incredibly well documented.

The scary part wasn't Stripe — it was making sure the payment-service and booking-service stayed in sync. If a payment succeeded but the booking update failed, we'd have a ghost payment.

I handled this with a simple event-based approach using Feign Client callbacks. Not perfect, but it worked for the scope of this project.

What I Learned

  1. Config Server saves you from config hell. Centralise early.
  2. Service discovery with Eureka feels like magic — until it doesn't register and you spend 2 hours debugging port conflicts.
  3. SLF4J logging with correlation IDs makes debugging distributed systems actually possible.
  4. Mockito tests forced me to think about dependencies in a way unit tests on monoliths never did.

Would I Use Microservices for Every Project?

No. Absolutely not.

For a small project, this was massively over-engineered. But the goal was to learn — and I learned more from this one project than from months of tutorials.

If you're learning Spring Boot, build a monolith first. Then break it apart. You'll understand why microservices exist, not just how to use them.

The app is live (locally 😅). Stripe works. JWT works. Eureka registers all five services.

And honestly? That feeling when all five services start up and talk to each other for the first time?

Pure magic. ✨

GitHub
LinkedIn