Skip to main content
Microservices & Event-Driven Architecture Verified Public RepositoryMulti-Service Suite

FitTrack: Distributed Microservices Platform & Asynchronous AI Engine

An end-to-end fitness tracking ecosystem built with Java 21, Spring Boot 3, Spring Cloud Gateway, Eureka, RabbitMQ event queues, Keycloak PKCE authentication, polyglot persistence (PostgreSQL + MongoDB Atlas), and Google Gemini LLM integration.

ArchitectureDecomposed Microservices
Backend StackJava 21 · Spring Boot 3.x
Messaging & AIRabbitMQ · Google Gemini
Databases & AuthPostgres · Mongo · Keycloak
Source Repository Distributed Local Environment (Java 21 + RabbitMQ + Keycloak)
FitTrack Distributed Microservices Topology & Event-Driven AI Architecture
01 / Background & Motivation

Why Microservices for Fitness Telemetry & AI Processing?

In traditional monolithic fitness architectures, high-throughput activity ingestion (e.g., GPS points, cadence, heart rate, calories) shares resources with user identity management and heavy computational workloads like AI-based workout recommendations. This introduces severe systemic vulnerabilities:

  • Synchronous Blocking by LLMs: Calling a Large Language Model (e.g. Gemini) can take anywhere from 1.5 to 4 seconds. Forcing mobile or web clients to wait synchronously stalls HTTP worker threads and degrades user responsiveness.
  • Schema Rigidity vs. Dynamic Telemetry: Storing user authentication tables alongside polymorphic workout metrics (running pace vs. weightlifting sets/reps) in a single relational schema forces sparse columns or anti-pattern JSON blobs.
  • Tight Coupling & Single Points of Failure: If the recommendation engine crashes under heavy load, the core user login and activity logging endpoints should remain unaffected.

FitTrack tackles this challenge with a distributed, event-driven microservices architecture: services have isolated data stores, communicate asynchronously via RabbitMQ, discover each other dynamically with Netflix Eureka, and route through a reactive Spring Cloud Gateway with Keycloak identity management.

02 / Microservice Topology

Six Autonomous Backend Services & React Frontend

Every backend service is an independent Spring Boot application with its own database and configuration profile. Configuration is pulled at startup from a central Config Server, and service instances register with Eureka for dynamic discovery.

1. Config ServerPort: 8888

Centralized configuration authority. Downstream services pull their environment configuration (DB URLs, credentials, Eureka URIs) at boot time via spring.config.import.

2. Eureka Discovery ServerPort: 8761

Service registry providing heartbeat monitoring and client-side load balancing via lb://SERVICE-NAME. Enables services to discover each other without static IP addresses.

3. Spring Cloud GatewayPort: 8080

Reactive reverse proxy (WebFlux). Validates Keycloak JWTs against JWKS certificates, injects security headers, and routes requests to /api/users, /api/activities, and /api/recommendations.

4. User ServicePort: 8081

User management and identity mapping. Backed by PostgreSQL (Supabase) via Spring Data JPA. Exposes validation endpoints consumed by Activity Service before activity persistence.

5. Activity ServicePort: 8082

Workout tracking engine backed by MongoDB Atlas. Validates users via WebClient, saves polymorphic activity documents, and acts as RabbitMQ producer to broadcast workout events.

6. AI Recommendation ServicePort: 8083

Asynchronous RabbitMQ consumer listening to activity.queue. Queries Google Gemini REST API, generates structured recovery insights, and writes recommendations to MongoDB.

Microservices Topology & Message Bus
Polyglot (PostgreSQL + MongoDB Atlas)
End-to-End System Communication Topology
                       ┌──────────────────────────────────────────────┐
                       │          React 19 + Vite Frontend            │
                       │     (Port 5173 · MUI v9 · Redux Toolkit)     │
                       └───────────────────────┬──────────────────────┘
                                               │ HTTP (Bearer JWT + X-User-ID)
                                               ▼
                       ┌──────────────────────────────────────────────┐
                       │           Spring Cloud Gateway               │
                       │        (Port 8080 · Reactive WebFlux)        │
                       └───────────────┬──────────────────────┬───────┘
                                       │                      │
             ┌─────────────────────────┴─────────┐            │
             ▼                                   ▼            ▼
 ┌──────────────────────┐             ┌──────────────────────────┐
 │     User Service     │<──WebClient─┤     Activity Service     │
 │ (Port 8081·Postgres) │ (Validation)│ (Port 8082·MongoDB Atlas)│
 └──────────────────────┘             └─────────────┬────────────┘
                                                    │
                                                    │ AMQP: fitness.exchange / activity.tracking
                                                    ▼
                                      ┌──────────────────────────┐
                                      │   RabbitMQ Event Broker  │
                                      │  (Port 5672·activity.queue)
                                      └─────────────┬────────────┘
                                                    │
                                                    │ Async Consume
                                                    ▼
                                      ┌──────────────────────────┐
                                      │  AI Recommendation Service│
                                      │(Port 8083·MongoDB Atlas) │
                                      └─────────────┬────────────┘
                                                    │
                                                    │ HTTPS (Prompt / JSON Generation)
                                                    ▼
                                      ┌──────────────────────────┐
                                      │     Google Gemini API    │
                                      └──────────────────────────┘
03 / Request Flow & Event Processing

From Workout Submission to AI Insights

1
Authentication via OAuth2 PKCE:

User signs in through Keycloak (port 8181). Frontend performs authorization code exchange with PKCE verification and extracts sub claim as X-User-ID.

2
Gateway JWT Enforcement:

React client submits POST /api/activities with Bearer JWT. Gateway verifies JWT validity against Keycloak’s JWKS endpoint (/protocol/openid-connect/certs) before proxying to Activity Service.

3
Inter-Service User Verification:

Activity Service validates that the user exists by executing a non-blocking GET /api/users/{userId}/validate call to User Service via Spring WebClient.

4
Storage & Immediate Response:

Activity is saved into MongoDB Atlas. The endpoint returns 201 Created to the client in under 50ms, without blocking on AI generation.

5
Asynchronous RabbitMQ Ingestion:

Activity Service publishes message to fitness.exchange with routing key activity.tracking. AI Service consumes message from activity.queue, formats contextual prompt, invokes Google Gemini, and persists structured recommendation in MongoDB.

04 / Key Engineering Decisions

Architecture Trade-offs & Polyglot Persistence

Asynchronous RabbitMQ vs. Synchronous REST

Calling LLM APIs involves latency spikes and potential rate limiting. Offloading AI recommendation generation to an AMQP message queue decouples user-facing activity logging latency from external API response times and ensures reliable message redelivery.

Polyglot Persistence: PostgreSQL + MongoDB

Relational PostgreSQL (Supabase) handles User identities, unique email constraints, and roles where ACID guarantees are essential. MongoDB Atlas handles fitness activities and AI recommendations, accommodating flexible additionalMetrics maps (pace, cadence, reps) across 8 distinct workout types.

OAuth2 Authorization Code with PKCE

Standard authorization code grant requires a client secret, which cannot be securely stored in single-page applications. Implementing PKCE (Proof Key for Code Exchange) cryptographically verifies that the code exchange request originates from the same browser instance that initiated login.

Centralized Configuration Management

Instead of managing isolated application.yml files across six microservices, the Spring Cloud Config Server provides single-point versioning for database credentials, RabbitMQ hosts, and JWT verification endpoints.

05 / Implementation Verification & Tested Scenarios

Verified Endpoints & AI Output Structure

The system supports full CRUD operations across user profiles, activities, and recommendations:

✓ Supported Activities & Metrics

Activity types: RUNNING, WALKING, CYCLING, WEIGHT_TRAINING, YOGA, CARDIO, STRETCHING, OTHER.

AI Recommendation Schema Generated via Gemini:
  • Analysis: Performance evaluation based on pace, heart rate, and duration.
  • Improvements: Actionable suggestions for recovery and training volume.
  • Suggestions: Recommended next session focus.
  • Safety: Injury prevention and hydration alerts based on max metrics.
06 / Honest Limitations & Operational Scope

Operational Complexities & Production Considerations

Operating a multi-service distributed suite presents distinct challenges that are honestly documented in the repository:

1. Multi-Service Startup Order

Services must be booted in strict sequence: Config Server (8888) → Eureka (8761) → Gateway (8080) → User Service (8081) → Activity Service (8082) → AI Service (8083). In a production cloud setting, Kubernetes readiness probes or container orchestrators would manage health gating automatically.

2. Eventual Consistency on UI

Because AI recommendations are processed asynchronously, navigating immediately to an activity detail page displays a placeholder until the Gemini response is generated and persisted. The frontend polls or expects 404 until generation concludes.

3. Dead-Letter Queue (DLQ) Absence

The current RabbitMQ configuration does not include an explicit Dead-Letter Exchange (DLX). If the Gemini API experiences sustained downtime or unparseable JSON responses, failed messages require manual retry rather than automated DLQ routing.

4. Cloud Deployment Footprint

Running 6 Java virtual machines (JVMs) alongside Keycloak and RabbitMQ requires substantial memory overhead. The system is designed and tested as a local distributed testbed; deploying to production would benefit from GraalVM native image compilation to reduce RAM footprint.