Book-Store Microservice
Built With •
Architecture •
Installation •
Project Structure •
Endpoints •
Deployment •
License
Built With
Architecture
Saga pattern for distributed transaction
Endpoints
Authentication Service Endpoints
Public Endpoints
GET /auth_v1/auth
- Health check
Authentication Endpoints
POST /auth_v1/auth/login
POST /auth_v1/auth/logout
POST /auth_v1/auth/refresh-token
Book Service Endpoints
Public Endpoints
GET /book_v1/book
- Health check
GET /book_v1/book/cover/:fileName
GET /book_v1/book
GET /book_v1/book/:id
GET /book_v1/book/tags
Authorized Endpoints (User who bought book or Admin Access)
GET /book_v1/book/read/:bookID
Admin-only CRUD Endpoints
GET /book_v1/admin/book
GET /book_v1/admin/book/:id
POST /book_v1/book
PATCH /book_v1/book/:id
PATCH /book_v1/book/cover/:id
PATCH /book_v1/book/file/:id
Order Service Endpoints
Public Endpoints
GET /order_v1/order
- Health check
Authorized Endpoints (User Access Only)
POST /order_v1/order/buy
GET /order_v1/order/myorder
GET /order_v1/order
Shelf Service Endpoints
Public Endpoints
GET /shelf_v1/shelf
- Health check
Authorized Endpoints (User Access Only)
User Service Endpoints
Public Endpoints
GET /user_v1/user
- Health check
POST /user_v1/user/register
POST /user_v1/webhook
- Stripe webhook
Authorized Endpoints (User Access Only)
POST /user_v1/user/top-up
GET /user_v1/user/top-up/:id
GET /user_v1/user/balance
GET /user_v1/user/profile
Admin-only Endpoints
POST /user_v1/user/transaction
GET /user_v1/user/transaction
Installation
-
Clone the repository:
git clone https://github.com/KritAsawaniramol/book-store.git
cd book-store
-
Install dependencies:
go mod tidy
-
Set up environment variables (fill in spaces in every .env file in env/dev)
-
Run the project:
go run main.go ./env/dev/.env.auth
go run main.go ./env/dev/.env.item
go run main.go ./env/dev/.env.player
go run main.go ./env/dev/.env.inventory
go run main.go ./env/dev/.env.payment
Project Structure
.
├── 📄 README.md
├── 📁 asset
│ └── 📁 image
│ └── 📁 bookCover
│ └── 📁 default
│ └── 🖼️ book-store_default_bookCover.png
├── 📁 build
│ ├── 📄 Dockerfile
│ ├── 📁 auth
│ │ ├── 📄 auth-deployment-github.yml
│ │ └── 📄 auth-service.yml
│ ├── 📁 book
│ │ ├── 📄 book-deployment-github.yml
│ │ └── 📄 book-service.yml
│ ├── 📄 book-store-ingress.yml
│ ├── 📁 order
│ │ ├── 📄 order-deployment-github.yml
│ │ └── 📄 order-service.yml
│ ├── 📁 shelf
│ │ ├── 📄 shelf-deployment-github.yml
│ │ └── 📄 shelf-service.yml
│ └── 📁 user
│ ├── 📄 user-deployment-github.yml
│ └── 📄 user-service.yml
├── 📄 command.txt
├── 📁 config
│ └── 📄 config.go
├── 📄 docker-compose.yml
├── 📁 env
│ ├── 📁 dev
│ │ ├── 📄 .env.auth
│ │ ├── 📄 .env.book
│ │ ├── 📄 .env.order
│ │ ├── 📄 .env.shelf
│ │ └── 📄 .env.user
│ ├── 📁 prod
│ │ └── 📄 .env
│ └── 📁 test
│ └── 📄 .env
├── 📄 go.mod
├── 📄 go.sum
├── 📄 main.go
├── 📁 models
│ └── 📄 pagination.go
├── 📁 module
│ ├── 📁 auth
│ │ ├── 📄 authEntity.go
│ │ ├── 📁 authHandler
│ │ │ ├── 📄 authGrpcHandler.go
│ │ │ ├── 📄 authGrpcHandler_test.go
│ │ │ ├── 📄 authHttpHandler.go
│ │ │ └── 📄 authHttpHandler_test.go
│ │ ├── 📄 authModel.go
│ │ ├── 📁 authPb
│ │ │ ├── 📄 authPb.pb.go
│ │ │ ├── 📄 authPb.proto
│ │ │ └── 📄 authPb_grpc.pb.go
│ │ ├── 📁 authRepository
│ │ │ ├── 📄 authRepository.go
│ │ │ ├── 📄 authRepositoryImpl.go
│ │ │ ├── 📄 authRepositoryMock.go
│ │ │ └── 📄 authRepository_test.go
│ │ ├── 📁 authUsecase
│ │ │ ├── 📄 authUsecase.go
│ │ │ ├── 📄 authUsecaseImpl.go
│ │ │ ├── 📄 authUsecaseMock.go
│ │ │ └── 📄 authUsecase_test.go
│ │ └── 📄 auth_err.go
│ ├── 📁 book
│ │ ├── 📄 bookEntity.go
│ │ ├── 📁 bookHandler
│ │ │ ├── 📄 bookGrpcHandler.go
│ │ │ └── 📄 bookHttpHandler.go
│ │ ├── 📄 bookModel.go
│ │ ├── 📁 bookPb
│ │ │ ├── 📄 bookPb.pb.go
│ │ │ ├── 📄 bookPb.proto
│ │ │ └── 📄 bookPb_grpc.pb.go
│ │ ├── 📁 bookRepository
│ │ │ ├── 📄 bookRepository.go
│ │ │ └── 📄 bookRepositoryImpl.go
│ │ └── 📁 bookUsecase
│ │ ├── 📄 bookUsecase.go
│ │ └── 📄 bookUsecaseImpl.go
│ ├── 📁 middleware
│ │ ├── 📁 middlewareHandler
│ │ │ └── 📄 middlewareHttpHander.go
│ │ ├── 📁 middlewareRepository
│ │ │ ├── 📄 middlewareRepositoryImpl.go
│ │ │ └── 📄 middlewareRepositoy.go
│ │ └── 📁 middlewareUsecase
│ │ ├── 📄 middlewareUsecase.go
│ │ └── 📄 middlewareUsecaseImpl.go
│ ├── 📁 order
│ │ ├── 📄 orderEntity.go
│ │ ├── 📁 orderHandler
│ │ │ ├── 📄 orderConsumeHandler.go
│ │ │ └── 📄 orderHttpHandler.go
│ │ ├── 📄 orderModel.go
│ │ ├── 📁 orderRepository
│ │ │ ├── 📄 orderRepository.go
│ │ │ └── 📄 orderRepositoryImpl.go
│ │ └── 📁 orderUsecase
│ │ ├── 📄 orderUsecase.go
│ │ └── 📄 orderUsecaseImpl.go
│ ├── 📁 shelf
│ │ ├── 📄 shelfEntity.go
│ │ ├── 📁 shelfHandler
│ │ │ ├── 📄 shelfConsumeHandler.go
│ │ │ ├── 📄 shelfGrpcHandler.go
│ │ │ ├── 📄 shelfHttpHandler.go
│ │ │ └── 📄 shelfQueueHandler.go
│ │ ├── 📄 shelfModel.go
│ │ ├── 📁 shelfPb
│ │ │ ├── 📄 shelfPb.pb.go
│ │ │ ├── 📄 shelfPb.proto
│ │ │ └── 📄 shelfPb_grpc.pb.go
│ │ ├── 📁 shelfRepository
│ │ │ ├── 📄 shelfRepository.go
│ │ │ └── 📄 shelfRepositoryImpl.go
│ │ └── 📁 shelfUsecase
│ │ ├── 📄 shelfUsecase.go
│ │ └── 📄 shelfUsecaseImpl.go
│ └── 📁 user
│ ├── 📄 userEntity.go
│ ├── 📁 userHandler
│ │ ├── 📄 userComsumeHandler.go
│ │ ├── 📄 userGrpcHandler.go
│ │ ├── 📄 userHttpHandler.go
│ │ └── 📄 userQueueHandler.go
│ ├── 📄 userModel.go
│ ├── 📁 userPb
│ │ ├── 📄 userPb.pb.go
│ │ ├── 📄 userPb.proto
│ │ ├── 📄 userPb_grpc.pb.go
│ │ └── 📄 userPb_grpcMock.go
│ ├── 📁 userRepository
│ │ ├── 📄 userRepository.go
│ │ └── 📄 userRepositoryImpl.go
│ └── 📁 userUsecase
│ ├── 📄 userUsecase.go
│ └── 📄 userUsecaseImpl.go
├── 📁 pkg
│ ├── 📁 database
│ │ ├── 📄 database.go
│ │ ├── 📁 migration
│ │ │ └── 📄 migration.go
│ │ └── 📄 postgres.go
│ ├── 📁 grpccon
│ │ └── 📄 grpccon.go
│ ├── 📁 jwtAuth
│ │ └── 📄 jwtAuth.go
│ ├── 📁 queue
│ │ ├── 📄 kafka.go
│ │ └── 📁 topic
│ │ └── 📄 topic.go
│ └── 📁 request
│ ├── 📄 err.go
│ └── 📄 request.go
├── 📁 server
│ ├── 📄 auth.go
│ ├── 📄 book.go
│ ├── 📄 ginServer.go
│ ├── 📄 healthCheck.go
│ ├── 📄 order.go
│ ├── 📄 server.go
│ ├── 📄 shelf.go
│ └── 📄 user.go
├── 📁 test
│ └── 📄 auth_test.go
└── 📁 util
└── 📄 json.go
Usage
Running Tests
To run tests, use:
go test ./...
Running Docker Compose for PostgreSQL, pgAdmin, and Kafka
start docker compose for start pgAdmin, Kafka and create PostgreSQL database for each service
Run Docker Compose to start all services:
docker-compose up -d
Accessing a Container's Shell:
docker exec -it <container name> bash
Stopping Services:
docker-compose down
Deploy to Kubernetes Engine
Make sure you have the following installed:
- Docker
- kubectl (configured to access your Kubernetes cluster)
- Kubernetes cluster (e.g., GKE, EKS, or Minikube)
- NGINX Ingress Controller
Docker Build and Push
To build and push the Docker image to Docker Hub:
-
Build the Docker Image:
docker build -f ./build/Dockerfile -t <docker_hub_username>/book-store:latest .
-
Push the Image to Docker Hub:
docker image push <docker_hub_username>/book-store:latest
Replace <docker_hub_username>
with your Docker Hub username. This will upload your image to Docker Hub for deployment.
Kubernetes Configurations
Creating a ConfigMap
To create a ConfigMap from an environment file:
kubectl create configmap book-store-env --from-file=./env/prod/.env
Setting Up NGINX Ingress
- Deploy the NGINX Ingress Controller:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.0-beta.0/deploy/static/provider/cloud/deploy.yaml
- Apply the Ingress Resource:
kubectl apply -f ./build/book-store-ingress.yml
Applying Services and Deployments
- Apply Services:
kubectl apply -f ./build/auth/auth-service.yml
kubectl apply -f ./build/user/user-service.yml
kubectl apply -f ./build/book/book-service.yml
kubectl apply -f ./build/shelf/shelf-service.yml
kubectl apply -f ./build/order/order-service.yml
- Apply Deployments:
kubectl apply -f ./build/auth/auth-deployment.yml
kubectl apply -f ./build/user/user-deployment.yml
kubectl apply -f ./build/book/book-deployment.yml
kubectl apply -f ./build/shelf/shelf-deployment.yml
kubectl apply -f ./build/order/order-deployment.yml
Migration Database
dev
go run pkg/database/migration/migration.go ./env/dev/.env.auth
go run pkg/database/migration/migration.go ./env/dev/.env.book
go run pkg/database/migration/migration.go ./env/dev/.env.order
go run pkg/database/migration/migration.go ./env/dev/.env.shelf
go run pkg/database/migration/migration.go ./env/dev/.env.user
prod
go run pkg/database/migration/migration.go ./env/prod/.env.auth
go run pkg/database/migration/migration.go ./env/prod/.env.book
go run pkg/database/migration/migration.go ./env/prod/.env.order
go run pkg/database/migration/migration.go ./env/prod/.env.shelf
go run pkg/database/migration/migration.go ./env/prod/.env.user
Kafka
Create topic
dev:
go run pkg/queue/topic/topic.go ./env/prod/.env.book
prod:
go run pkg/queue/topic/topic.go ./env/prod/.env.book
Generate a Proto File Command
User
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
./module/user/userPb/userPb.proto
Auth
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
./module/auth/authPb/authPb.proto
Book
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
./module/book/bookPb/bookPb.proto
Shelf
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
./module/shelf/shelfPb/shelfPb.proto
Deployment
- Services: Deployed to Google Kubernetes Engine (GKE)
- Databases:
- Supabase
- Google Cloud SQL
- Front-end: Deployed to vercel
License
Distributed under the MIT License. See LICENSE for more information.
GitHub @kritAsawaniramol ·