The Bazaar Cart API is a Spring Boot microservice written in Kotlin, responsible for managing user shopping carts and wishlists across the Bazaar ecosystem. It handles state changes for users' carts and wishlists, while validating account status and product availability from sibling services.
- Core Features
- System Architecture
- Technology Stack
- Database Schema
- Environment Configuration
- Getting Started
- API Reference
- Background & Scheduled Jobs
- Cart & Wishlist Management:
- Add, update quantity, and remove items in user carts and wishlists.
- Cart structure and items mapped directly to MongoDB documents for fast access.
- Asynchronous Cart Wiping:
- Automatic cart purging listening to background events via RabbitMQ (
cart.queue) on checkout completion or user deletion.
- Automatic cart purging listening to background events via RabbitMQ (
- Access Control & User Validation:
- Custom stateless security filter checking for incoming proxy authorization (
X-User-Idheaders). - Synchronous active user verification querying the User Microservice to ensure requesting users are in
ACTIVEstate. Short-circuits with401 Unauthorizedif blocked.
- Custom stateless security filter checking for incoming proxy authorization (
- Microservice Integrations:
- Validates product existence and stock levels by communicating with the Catalog Microservice using declarative HTTP interfaces (
@HttpExchange).
- Validates product existence and stock levels by communicating with the Catalog Microservice using declarative HTTP interfaces (
- Observability & Health Checks:
- Integrated OpenTelemetry Javaagent for APM tracing & metrics (Tempo/Grafana).
- Actuator metrics, and dedicated, lightweight Liveness (
/actuator/health/liveness) and Readiness (/actuator/health/readiness) endpoints.
The Cart API operates in a routed architecture, designed to sit behind an API Gateway:
graph TD
Client([Client / App Mobile]) --> |HTTP Requests| Gateway[API Gateway]
Gateway -->|Forwards with X-User-Id header| CartService[Cart Microservice]
subgraph Cart Service Internals
CartService --> |Reads/Writes| MongoDB[(MongoDB Database)]
UserStatusFilter[UserStatusFilter] --> |Validates Account Status| CartService
end
CartService -->|HTTP Client| UserService[User Microservice]
CartService -->|HTTP Client| CatalogService[Catalog Microservice]
RabbitMQ[RabbitMQ Message Broker] -->|Delivers wipe events to cart.queue| WipeCartConsumer[WipeCartConsumer]
WipeCartConsumer -->|Wipes active cart| CartService
Note
Spring Security is configured to trust the API Gateway to inject authorization context via the X-User-Id header. The custom UserStatusFilter queries the User Microservice synchronously to check if the user account is currently active.
- Framework: Spring Boot 4.0.5, Spring Security, Spring Web, Spring Actuator, Spring AMQP
- Language: Kotlin 2.2.21 (Java 21 runtime)
- Database: MongoDB (via Spring Data MongoDB)
- Database Migrations: Mongock
- Asynchronous Messaging: RabbitMQ (AMQP Client)
- HTTP Clients: Declarative HTTP Interfaces (
@HttpExchange) backed by Spring'sRestClient - Monitoring & Observability: OpenTelemetry JVM Agent, Slf4j, Spring Boot Actuator
- Testing Tools: JUnit 5, MockK, SpringMockK, Testcontainers (MongoDB container integration)
Database migrations are managed automatically via Mongock change units (src/main/kotlin/com/example/cart/migrations):
V001_init: Establish initial baseline migration for MongoDB.
carts: Stores active carts indexed byuserIdas the primary key (_id).- Fields:
_id(userId: Long),items(List of CartItem subdocuments). - Each
CartItemcontainsproductId(Int),sellerId(Int?), andquantity(Int).
- Fields:
wishlists: Stores user wishlists indexed byuserIdas the primary key (_id).- Fields:
_id(userId: Long),items(List of WishlistItem subdocuments). - Each
WishlistItemcontainsproductId(Int) andsellerId(Int?).
- Fields:
To configure the application, create a .env file in the root directory based on the .env.example template:
cp .env.example .env| Variable | Description | Default / Example |
|---|---|---|
| Server Settings | ||
PORT |
Local port of the Spring Boot application | 8082 |
HOST |
Bind address of the service | 0.0.0.0 |
ENVIRONMENT |
Running environment mode (development, production) |
development |
| Database (MongoDB) | ||
MONGO_INITDB_ROOT_USERNAME |
Root database administrator username | admin |
MONGO_INITDB_ROOT_PASSWORD |
Password for the root Mongo database user | secret |
MONGO_DB |
Cart microservice database name | bazaar |
MONGO_HOST |
Database host name (use container name in Docker) | mongo |
MONGO_PORT |
Port inside the database docker container | 27017 |
MONGO_EXPOSE_PORT |
Host exposed port for MongoDB | 27017 |
| External APIs | ||
API_CATALOG_URL |
Microservice endpoint routing for Catalog API | https://localhost:8081/catalog |
API_USER_URL |
Microservice endpoint routing for User API | https://localhost:8080 |
| Message Broker (RabbitMQ) | ||
RABBIT_URL |
Connection URL for RabbitMQ broker instances | amqps://guest:guest@localhost:5671 |
| Telemetry (Grafana/OTel) | ||
OTEL_SERVICE_NAME |
Service label reported in OpenTelemetry traces | api-cart |
OTEL_EXPORTER_OTLP_PROTOCOL |
Protocol used to export traces to OTLP collector | otlp |
OTEL_EXPORTER_OTLP_ENDPOINT |
HTTP/gRPC collector endpoint for OpenTelemetry | http://tempo:4317 |
OTEL_EXPORTER_OTLP_HEADERS |
Optional authentication headers for OTel exporter | Authorization=Bearer... |
- Java Development Kit (JDK) 21
- Kotlin 2.2.21
- Maven 3.9+ (or use the provided
mvnwwrapper) - Docker & Docker Compose
To launch the microservice alongside its MongoDB dependency, run:
- Create the shared network (if not already existing):
docker network create bazaar-network
- Build and start the containers:
docker-compose up --build
- Stop the environment:
docker-compose down -v
For development, you can spin up the MongoDB database in Docker and run the Spring Boot app locally:
- Start MongoDB only:
docker-compose up mongo -d
- Compile and run the Spring Boot app:
./mvnw spring-boot:run
Run the test suite, which uses Testcontainers for database operations:
./mvnw testThe test coverage reports will be compiled at target/site/jacoco/index.html.
Interactive API documentation (Swagger UI) is available once the application runs at:
- Swagger UI: http://localhost:8082/swagger-ui.html
- OpenAPI Definition JSON: http://localhost:8082/v3/api-docs
Or if you use the service in the cloud, it is available at:
- Swagger UI:
https://api-cart-aiwm.onrender.com/swagger-ui/index.html#/ - OpenAPI Definition JSON:
https://api-cart-aiwm.onrender.com/v3/api-docs
Important
All Cart and Wishlist operations require the HTTP header X-User-Id to identify and authorize the calling user.
The service runs a background RabbitMQ consumer (WipeCartConsumer) listening to queue-based events:
- Listens on
cart.queuefor asynchronous user event notifications. - When an event is received, it triggers a cart cleanup (
wipeCart), ensuring that data states are automatically synchronized across system actions.