A Spring Boot backend implementation for the GoShop e-commerce platform, using MongoDB for data persistence and JWT-based authentication.
- Authentication: User signup, signin, signout with JWT cookies
- Product Management: Browse products by market, with automatic data seeding
- Shopping Cart: Anonymous and authenticated cart management with merge functionality
- Security: Spring Security with JWT, BCrypt password hashing
- Database: MongoDB with Spring Data MongoDB
- Static File Serving: Serves frontend files directly
- Java: 17+
- Framework: Spring Boot 3.2.0
- Database: MongoDB
- Security: Spring Security + JWT
- Build Tool: Gradle
- Java 17 or higher
- MongoDB (local or MongoDB Atlas)
- Gradle (included via wrapper)
On Ubuntu/Debian:
sudo apt-get install mongodb
sudo systemctl start mongodbUsing Docker:
docker run -d -p 27017:27017 --name mongodb mongo:latestUsing MongoDB Atlas: Sign up at https://www.mongodb.com/cloud/atlas and get your connection URI.
Create a .env file in the backend directory or set environment variables:
export MONGODB_URI=mongodb://localhost:27017/goshop
export JWT_SECRET=your-very-long-secret-key-at-least-32-characters-for-production
export PORT=8080Development mode:
cd backend
./gradlew bootRunWith specific profile:
./gradlew bootRun --args='--spring.profiles.active=dev'Build and run JAR:
./gradlew build
java -jar build/libs/goshop-backend-0.0.1-SNAPSHOT.jar- Frontend: http://localhost:8080
- API Base URL: http://localhost:8080/api
- Health Check: http://localhost:8080/health
| Endpoint | Method | Description |
|---|---|---|
/api/auth/signup |
POST | Create new user account |
/api/auth/signin |
POST | Sign in to existing account |
/api/auth/signout |
POST | Sign out and clear session |
/api/auth/me |
GET | Get current user info |
| Endpoint | Method | Description |
|---|---|---|
/api/products |
GET | Get all products (optional ?market=slug filter) |
/api/products/:id |
GET | Get single product |
| Endpoint | Method | Description |
|---|---|---|
/api/cart |
GET | Get current cart |
/api/cart/count |
GET | Get cart item count |
/api/cart/items |
POST | Add item to cart |
/api/cart/items/:id |
PATCH | Update cart item quantity |
/api/cart/items/:id |
DELETE | Remove item from cart |
/api/cart/merge |
POST | Merge anonymous cart with user cart |
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Health check endpoint |
backend/
├── src/
│ ├── main/
│ │ ├── java/com/goshop/
│ │ │ ├── GoShopApplication.java # Main application class
│ │ │ ├── config/ # Configuration classes
│ │ │ │ ├── SecurityConfig.java # Spring Security config
│ │ │ │ ├── MongoConfig.java # MongoDB config
│ │ │ │ └── WebConfig.java # Web/CORS config
│ │ │ ├── controller/ # REST controllers
│ │ │ │ ├── AuthController.java
│ │ │ │ ├── ProductController.java
│ │ │ │ ├── CartController.java
│ │ │ │ └── HealthController.java
│ │ │ ├── service/ # Business logic
│ │ │ │ ├── AuthService.java
│ │ │ │ ├── ProductService.java
│ │ │ │ └── CartService.java
│ │ │ ├── repository/ # MongoDB repositories
│ │ │ │ ├── UserRepository.java
│ │ │ │ ├── ProductRepository.java
│ │ │ │ └── CartRepository.java
│ │ │ ├── model/ # MongoDB documents
│ │ │ │ ├── User.java
│ │ │ │ ├── Product.java
│ │ │ │ ├── Cart.java
│ │ │ │ └── CartItem.java
│ │ │ ├── dto/ # Data Transfer Objects
│ │ │ │ ├── SignupRequest.java
│ │ │ │ ├── SigninRequest.java
│ │ │ │ ├── AddToCartRequest.java
│ │ │ │ ├── UpdateCartItemRequest.java
│ │ │ │ ├── UserResponse.java
│ │ │ │ ├── CartResponse.java
│ │ │ │ └── ErrorResponse.java
│ │ │ ├── security/ # JWT security
│ │ │ │ ├── JwtTokenProvider.java
│ │ │ │ └── JwtAuthenticationFilter.java
│ │ │ └── exception/ # Exception handling
│ │ │ ├── GlobalExceptionHandler.java
│ │ │ └── [custom exceptions]
│ │ └── resources/
│ │ ├── application.yml # Main config
│ │ ├── application-dev.yml # Dev config
│ │ └── application-prod.yml # Production config
│ └── test/
├── build.gradle # Gradle build config
├── settings.gradle # Gradle settings
└── gradlew # Gradle wrapper
The application automatically seeds the database with 9 products across 3 markets on first startup:
- Kaneshie Market: Fresh Bananas, Fresh Herbs, Fresh Tomatoes
- Accra Market: Roma Tomatoes, Imported Rice, Green Apples
- Kumasi Market: Garden Eggs, Kontomire Leaves, Local Red Rice
Main configuration file with sensible defaults:
spring:
data:
mongodb:
uri: ${MONGODB_URI:mongodb://localhost:27017/goshop}
security:
jwt:
secret: ${JWT_SECRET}
expiration: 604800000 # 7 days
server:
port: ${PORT:8080}| Variable | Description | Default |
|---|---|---|
MONGODB_URI |
MongoDB connection string | mongodb://localhost:27017/goshop |
JWT_SECRET |
Secret key for JWT signing | Must be set in production |
PORT |
Server port | 8080 |
The backend uses JWT tokens stored in HTTP-only cookies:
- Cookie Name:
SESSION - Expiration: 7 days
- Flags: httpOnly, sameSite=Lax
- Passwords are hashed using BCrypt with strength 10
- Original passwords are never stored
- Created automatically on first add-to-cart
- Tracked via
CART_IDcookie - 30-day expiration
- Tied to user ID
- Anonymous cart can be merged on login
./gradlew test./gradlew clean buildThe JAR file will be created in build/libs/.
Use Spring Boot DevTools for automatic restart on code changes:
./gradlew bootRunThis backend is a drop-in replacement for the Node.js backend:
- No Frontend Changes: All API endpoints maintain the same contract
- Cookie Compatibility: Uses same cookie names (SESSION, CART_ID)
- Response Format: Maintains identical JSON structure
- Status Codes: Returns same HTTP status codes
# Check if MongoDB is running
sudo systemctl status mongodb
# Start MongoDB
sudo systemctl start mongodb
# Check connection
mongo --eval "db.adminCommand('ping')"# Find process using port 8080
lsof -i :8080
# Kill the process
kill -9 <PID>
# Or use different port
export PORT=8081
./gradlew bootRunEnsure your JWT_SECRET is at least 32 characters long:
export JWT_SECRET="your-very-long-secret-key-minimum-32-characters-required-for-hmac-sha256"-
Set Environment Variables:
export SPRING_PROFILES_ACTIVE=prod export MONGODB_URI=your-production-mongodb-uri export JWT_SECRET=your-secure-secret-key export PORT=8080
-
Build the Application:
./gradlew clean build
-
Run the JAR:
java -jar build/libs/goshop-backend-0.0.1-SNAPSHOT.jar
-
Or use Docker:
FROM openjdk:17-slim COPY build/libs/goshop-backend-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java", "-jar", "/app.jar"]
MIT