Orderly is a full-featured RESTful API for an e-commerce platform, built with Spring Boot. It demonstrates clean service-layer architecture, modern API design principles, and production-grade DevOps integration.
The API supports complete CRUD operations across all major e-commerce entities and features secure Authentication, Authorization, and Role-Based Access Control (RBAC) implemented with Spring Security and JWT. All endpoints are fully documented and testable through Swagger/OpenAPI.
From a DevOps perspective, Orderly is:
- Containerized with Docker and orchestrated via Docker Compose.
- Backed by GitHub Actions for CI/CD automation.
- Hosted on AWS EC2, with Watchtower enabling automated container updates.
- Integrated with AWS S3 for external image storage.
Databases:
- π§© Local development β uses PostgreSQL, managed via Docker Compose
- βοΈ Production β uses PostgreSQL, provisioned through AWS RDS
- CRUD operations for all domain models (Product, Category, User, etc.).
- Role-Based Access Control (RBAC) to define user permissions.
- Shopping Cart Management (add, remove, update quantity, clear cart, checkout).
- Order Creation and tracking.
- Spring Security for securing endpoints.
- JWT (JSON Web Tokens) for stateless authentication.
- Two primary roles:
ADMINandCUSTOMER.
| Role | Permissions |
|---|---|
CUSTOMER |
Browse products, view categories, manage shopping cart, place orders. |
ADMIN |
All CUSTOMER permissions plus managing products, categories, users, and viewing all orders. |
- Dockerized application with multi-service setup via Docker Compose (Spring, PostgreSQL, Watchtower).
- GitHub Actions CI/CD pipeline for:
- Running unit tests
- Building Docker images
- Pushing images to GitHub Container Registry (GHCR)
- Deployed to AWS EC2 using the latest GHCR image.
- Automatic image updates handled by Watchtower.
| Layer | Technology |
|---|---|
| Framework | Spring Boot |
| Language | Java 21 |
| Database | PostgreSQL (Local via Docker Compose Β· Production via AWS RDS) |
| Cloud Storage | AWS S3 |
| Security | Spring Security, JWT |
| Containerization | Docker, Docker Compose |
| CI/CD | GitHub Actions |
| Deployment | AWS EC2 |
| Documentation | Swagger/OpenAPI |
| Testing | JUnit, Mockito |
The API is built around the following essential e-commerce models:
User: User details and authentication information.Role: User roles (e.g.,ADMIN,CUSTOMER).Product: Details of an item for sale.Image: Product image metadata (actual images stored in AWS S3).Category: Classification for products.Cart: A user's current collection of items before checkout.CartItem: An individual item within aCartwith quantity.Order: A confirmed transaction.OrderItem: An individual item within a completedOrder.
- Java 21+
- Maven
- Docker & Docker Compose
-
Clone the repository:
git clone https://github.com/iodsky/orderly.git cd orderly -
Configure the environment:
- The application uses three YAML configuration files for different environments:
application.yml- Base configuration (shared across all environments)application-local.yml- Local development configurationapplication-prod.yml- Production configuration
- You will also need a
.envfile (see the Environment Variables section below).
Example
# application.yml spring: application: name: orderly server: port: ${PORT} servlet: context-path: /api security: jwt: secret-key: ${JWT_SECRET_KEY} expiration-time: ${JWT_EXPIRATION_TIME} springdoc: api-docs: path: /docs swagger-ui: path: /swagger-ui.html aws: s3: region: ${AWS_S3_REGION} bucket: ${AWS_S3_BUCKET} base-folder: ${AWS_S3_BASE_FOLDER}
# application-local.yml spring: config: activate: on-profile: local datasource: url: jdbc:postgresql://${LOCAL_DB_HOST}:${LOCAL_DB_PORT}/${LOCAL_DB} username: ${LOCAL_DB_USER} password: ${LOCAL_DB_PASSWORD} driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: update properties: hibernate: format_sql: true show_sql: true dialect: org.hibernate.dialect.PostgreSQLDialect defer-datasource-initialization: true sql: init: mode: always aws: s3: access-key: ${AWS_ACCESS_KEY_ID} secret-key: ${AWS_SECRET_ACCESS_KEY}
- The application uses three YAML configuration files for different environments:
-
Run locally:
# Start only the development database docker compose -f compose.db.yml up -d # Run the Spring Boot app on the host with the local profile ./mvnw spring-boot:run -Dspring.profiles.active=local
The API will be accessible at http://localhost:8000/api.
The project includes two Docker Compose configurations for different environments.
This setup runs only PostgreSQL for local development. The Spring Boot app runs on the host.
Usage:
docker-compose -f compose.db.yml up -dThis will:
- Run PostgreSQL with credentials from LOCAL_DB_* variables.
- Expose PostgreSQL on port 5432.
The production configuration is optimized for deployment on AWS EC2 and uses a pre-built Docker image from the GitHub Container Registry (GHCR) instead of rebuilding locally.
Usage:
docker-compose -f compose.prod.yml up -dThis will:
- Run the API with the prod profile.
- Connect it to a PostgreSQL database via AWS RDS.
- Uses Watchtower to automatically update the container when a new image is pushed to GHCR.
- Sends update notifications via email.
All configuration values are managed through a .env file (excluded from version control). An example template is provided in .env.template:
# Server
PORT=
SPRING_PROFILES_ACTIVE=local
# JWT
JWT_SECRET_KEY=
JWT_EXPIRATION_TIME=
# Production datasource
CLOUD_DB=
CLOUD_DB_HOST=
CLOUD_DB_PORT=
CLOUD_DB_USER=
CLOUD_DB_PASSWORD=
# Development datasource (used by application-local.yml and compose.db.yml)
LOCAL_DB=
LOCAL_DB_HOST=
LOCAL_DB_PORT=
LOCAL_DB_USER=
LOCAL_DB_PASSWORD=
# AWS S3
AWS_S3_REGION=
AWS_S3_BUCKET=
AWS_S3_BASE_FOLDER=
# AWS (dev)
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
# Watchtower
WATCHTOWER_EMAIL_FROM=
WATCHTOWER_EMAIL_TO=
WATCHTOWER_EMAIL_SERVER=
WATCHTOWER_EMAIL_USER=
WATCHTOWER_EMAIL_PASSWORD=Usage
- Copy the template:
cp .env.template .env
- Fill in your values in
.env. - Docker Compose will automatically load these environment variables during startup.
Once the application is running, the Swagger UI for testing and viewing all endpoints is available at:
[Swagger URL: http://localhost:8000/api/swagger-ui.html]
To run the unit tests for the Service layer:
./mvnw testThe following enhancements are planned to evolve Orderly by integrating industry-standard practices and expanding my skill set, making the project a more complete demonstration of modern API architecture:
-
Containerization with Docker: The immediate next step is to Dockerize the Spring Boot application to master containerization and ensure a consistent, easily portable development environment.
-
Production Database Migration (PostgreSQL on AWS RDS): The production database has been successfully migrated from MySQL to PostgreSQL, hosted on AWS RDS for improved reliability, scalability, and performance.
-
Secure HTTPS Configuration (Traefik): HTTPS has been fully implemented using Traefik as a reverse proxy and certificate manager, ensuring encrypted and secure production traffic.
-
External Image Storage (AWS S3): Integrating Amazon Simple Storage Service (S3) will teach valuable skills in handling external object storage. This practice of decoupling image storage from the database is a core architectural pattern for scalable applications.
-
CI/CD Pipeline & Cloud Deployment (AWS):
- Implement a Continuous Integration/Continuous Deployment (CI/CD) pipeline using GitHub Actions.
- Deployed the containerized API to an AWS EC2 instance, configured to automatically pull and restart the latest image via Watchtower.
-
Monitoring & Observability: Implement centralized logging and metrics monitoring using tools like Prometheus and Grafana.
