Welcome to the Budget Management API, a robust, microservices backend platform for managing budgets, expenses, users, orders, and notifications. Built with Node.js, Express, and TypeScript, it supports advanced features like GraphQL, gRPC, WebSockets, and REST APIs.
The API also integrates with PostgreSQL, MongoDB, MySQL, Redis, RabbitMQ, Kafka, and Elasticsearch, and is containerized with Docker and orchestrated using Kubernetes that fully supports zero-downtime deployment (blue/green & canary deployment). It also includes a developer-friendly CLI tool and interactive Swagger/OpenAPI documentation for exploring and testing endpoints.
Below is a very comprehensive guide to setting up, running, and utilizing this API. πΈπ
The Budget Management API is designed to handle complex budget management requirements, including:
dotnet and spring-boot backends to demonstrate integration with other technologies.The purpose of this API is to demonstrate the capabilities of modern backend technologies and provide a foundation for building scalable, real-time applications. It can be used as a reference for developers looking to implement similar features in their projects. Simply clone the repository, set up the environment, and start building the frontend or additional functionality on top of the existing API!
The Budget Management API is deployed live at https://budget-management-backend-api.onrender.com.
Additionally, a mock frontend UI is also available, hosted at https://budget-manage-app.vercel.app.
You can access the API and test the endpoints directly from the browser. Feel free to use the API for your own projects or applications. Simply add some attribution to the original repository and the creator. Also, be sure that you use your own credentials and tokens, otherwise your data may clash with mine and other usersβ data!
[!IMPORTANT] Be mindful of the rate limits and usage policies when testing the live API. Additionally, because the API is hosted on the free plan of Render, it may take a while (1-2 minutes) to wake up if it has been inactive for some time. Kindly be patient during this process!
[!NOTE] Backup Frontend: https://budget-management-system.netlify.app.
| Technology | Purpose |
|---|---|
| Node.js | Core application framework. |
| Express.js | Web application framework for building APIs. |
| MongoDB | Primary NoSQL database for managing budgets and expenses. |
| PostgreSQL | Relational database for transaction logs. |
| MySQL | Optional relational database support. |
| Redis | In-memory database for caching. |
| RabbitMQ | Message broker for task queuing. |
| Kafka | Distributed event streaming platform. |
| Elasticsearch | Advanced search engine for querying data. |
| gRPC | High-performance remote procedure call framework. |
| GraphQL | Query language for fetching and manipulating data. |
| WebSocket | Real-time communication for notifications. |
| Swagger/OpenAPI | API documentation and testing. |
| Docker | Containerization for easy deployment. |
| Kubernetes | Orchestrating containerized applications at scale. |
| Nginx | Reverse proxy and load balancer. |
| Prometheus | Monitoring and alerting toolkit. |
| Grafana | Observability and visualization platform. |
| Jenkins | CI/CD pipeline for automated testing and deployment. |
The Budget Management API is designed with a microservices architecture, allowing for modular development and deployment. Each service can be developed, deployed, and scaled independently, providing flexibility and resilience.
This architecture allows for easy integration of additional services, such as order management, task management, and notification services, without affecting the core functionality of the API.
Each service communicates with others using RabbitMQ for asynchronous messaging, gRPC for high-performance remote procedure calls, and REST APIs for standard HTTP communication. This ensures that services can operate independently while still being able to interact with each other as needed.
Also, the API is designed to be modular, allowing for easy addition of new services or features without disrupting existing functionality. This modularity is achieved through the use of separate directories for each service, with shared utilities and configurations in a common structure.
[!TIP] Each service does not live in its own directory, but rather is organized within the main project structure. This allows for easier management and deployment of the entire application as a single unit, while still maintaining the modularity of the microservices architecture.
[!NOTE] This diagram illustrates the microservices architecture of the Budget Management API, showing how different services interact with each other and external clients. Each service can be independently developed and deployed, allowing for scalability and maintainability.
[!NOTE] This architecture diagram illustrates the modular nature of the Budget Management API, showcasing how different services interact with each other and external clients. It also highlights the use of various technologies such as Docker, Kubernetes, and Nginx for deployment and scaling.
mindmap
root((Budget-Management-Backend-API))
Root Files
".env"[.env β Environment variables configuration]
".env.example"[.env.example β Sample environment config]
".gitignore"[.gitignore β Git ignore rules]
".prettierrc"[.prettierrc β Prettier formatting config]
LICENSE[LICENSE β Project license]
README[README.md β Project documentation]
cli.js[cli.js β CLI tool for backend]
docker-compose.yml[docker-compose.yml β Docker Compose configuration]
Dockerfile[Dockerfile β Backend container image]
grpcServer.js[gRPC server implementation]
index.js[Main application entry point]
nodemon.json[nodemon.json β Dev server reload config]
openapi.yaml[openapi.yaml β API specification]
package.json[package.json β NPM configuration]
prometheus.yml[prometheus.yml β Monitoring configuration]
start.sh[start.sh β Startup script]
Tests
"__tests__/app.test.js"[__tests__/app.test.js β Main test file]
Docs
"docs/swaggerConfig.js"[swaggerConfig.js β Swagger setup]
GraphQL
"graphql/schema.js"[schema.js β GraphQL schema definition]
Proto
"proto/budget.proto"[budget.proto β gRPC proto file]
NGINX
"nginx/docker-compose.yml"[docker-compose.yml β NGINX stack]
"nginx/Dockerfile"[Dockerfile β NGINX image]
"nginx/nginx.conf"[nginx.conf β Reverse proxy config]
"nginx/start_nginx.sh"[start_nginx.sh β NGINX start script]
"nginx/README.md"[README.md β NGINX documentation]
Redis-Mongo Flow
"redis-mongo-flow/app.js"[app.js β Express app for Redis-Mongo flow]
"redis-mongo-flow/config.js"[config.js β Flow configuration]
"redis-mongo-flow/package.json"[package.json β Module dependencies]
"redis-mongo-flow/README.md"[README.md β Flow documentation]
"redis-mongo-flow/seed.js"[seed.js β Data seeder]
"redis-mongo-flow/test.js"[test.js β Flow test script]
Round-Robin Load Balancer
"round-robin/config.js"[config.js β Load balancer configuration]
"round-robin/index.js"[index.js β Round-robin logic]
"round-robin/README.md"[README.md β Load balancer docs]
Services
"services/dataSeeder.js"[dataSeeder.js β MongoDB seeder]
"services/elasticService.js"[elasticService.js β Elasticsearch utilities]
"services/jwtService.js"[jwtService.js β JWT helpers]
"services/postgresService.js"[postgresService.js β PostgreSQL utilities]
"services/rabbitMQService.js"[rabbitMQService.js β RabbitMQ client]
"services/redisService.js"[redisService.js β Redis client]
"services/websocketService.js"[websocketService.js β WebSocket server]
Controllers
"controllers/authController.js"[authController.js β Authentication endpoints]
"controllers/budgetController.js"[budgetController.js β Budget endpoints]
"controllers/customerController.js"[customerController.js β Customer endpoints]
"controllers/expenseController.js"[expenseController.js β Expense endpoints]
"controllers/notificationController.js"[notificationController.js β Notification endpoints]
"controllers/orderController.js"[orderController.js β Order endpoints]
"controllers/searchController.js"[searchController.js β Elasticsearch endpoints]
"controllers/taskController.js"[taskController.js β Task endpoints]
"controllers/transactionController.js"[transactionController.js β Transaction log endpoints]
"controllers/userController.js"[userController.js β User profile endpoints]
Middleware
"middleware/authMiddleware.js"[authMiddleware.js β JWT authentication middleware]
Models
"models/budget.js"[budget.js β Budget schema]
"models/customer.js"[customer.js β Customer schema]
"models/expense.js"[expense.js β Expense schema]
"models/order.js"[order.js β Order schema]
"models/task.js"[task.js β Task schema]
"models/user.js"[user.js β User schema]
Routes
"routes/authRoutes.js"[authRoutes.js β Auth routes]
"routes/budgetRoutes.js"[budgetRoutes.js β Budget routes]
"routes/customerRoutes.js"[customerRoutes.js β Customer routes]
"routes/expenseRoutes.js"[expenseRoutes.js β Expense routes]
"routes/graphqlRoutes.js"[graphqlRoutes.js β GraphQL routes]
"routes/index.js"[index.js β Router entry point]
"routes/notificationRoutes.js"[notificationRoutes.js β Notification routes]
"routes/orderRoutes.js"[orderRoutes.js β Order routes]
"routes/searchRoutes.js"[searchRoutes.js β Elasticsearch routes]
"routes/taskRoutes.js"[taskRoutes.js β Task routes]
"routes/transactionRoutes.js"[transactionRoutes.js β Transaction routes]
"routes/userRoutes.js"[userRoutes.js β User profile routes]
Views
"views/android-chrome-192x192.png"[android-chrome-192x192.png β Icon]
"views/android-chrome-512x512.png"[android-chrome-512x512.png β Icon]
"views/apple-touch-icon.png"[apple-touch-icon.png β Icon]
"views/favicon.ico"[favicon.ico β Favicon]
"views/favicon-16x16.png"[favicon-16x16.png β Icon]
"views/favicon-32x32.png"[favicon-32x32.png β Icon]
"views/home.html"[home.html β Homepage template]
"views/manifest.json"[manifest.json β Web app manifest]
Other
"and many more files..."[Additional supporting files and directories]
git clone https://github.com/hoangsonww/Budget-Management-Backend-API.git
cd Budget-Management-Backend-API
npm install
.env file in the root directory:
MONGO_DB_URI=mongodb://localhost:27017/budget_manager
POSTGRES_URI=postgres://user:password@localhost:5432/budget_manager
REDIS_URL=redis://localhost:6379
RABBITMQ_URL=amqp://localhost
KAFKA_BROKER=localhost:9092
JWT_SECRET=your_secret_key
npm start
http://localhost:3000http://localhost:3000/docs| Endpoint | Method | Description |
|---|---|---|
/api/auth/register |
POST | Register a new user. |
/api/auth/login |
POST | Login and receive a JWT token. |
/api/auth/logout |
POST | Logout and invalidate the token. |
/api/auth/verify-email |
POST | Verify the userβs email address. |
/api/auth/reset-password |
POST | Reset the userβs password. |
/api/users/profile |
GET | Get the authenticated userβs profile. |
/api/budgets |
GET | Get all budgets. |
/api/budgets |
POST | Create a new budget. |
/api/budgets/:id |
GET | Get a specific budget. |
/api/budgets/:id |
PUT | Update a budget. |
/api/budgets/:id |
DELETE | Delete a budget. |
/api/customers |
GET | Get all customers. |
/api/customers |
POST | Create a new customer. |
/api/customers/:id |
GET | Get a specific customer. |
/api/customers/:id |
PUT | Update a customer. |
/api/customers/:id |
DELETE | Delete a customer. |
/api/expenses |
GET | Get all expenses. |
/api/expenses |
POST | Add a new expense. |
/api/expenses/:budgetId |
GET | Get all expenses for a budget. |
/api/expenses/:id |
PUT | Update an expense. |
/api/expenses/:id |
DELETE | Delete an expense. |
/api/orders |
GET | Get all orders. |
/api/orders |
POST | Create a new order. |
/api/orders/:id |
GET | Get a specific order. |
/api/orders/:id |
PUT | Update an order. |
/api/orders/:id |
DELETE | Delete an order. |
/api/transactions |
GET | Get all transactions. |
/api/transactions |
POST | Add a new transaction. |
/api/transactions/:id |
GET | Get a specific transaction. |
/api/transactions/:id |
PUT | Update a transaction. |
/api/transactions/:id |
DELETE | Delete a transaction. |
/api/tasks |
GET | Get all tasks. |
/api/tasks |
POST | Add a new task. |
/api/tasks/:id |
GET | Get a specific task. |
/api/tasks/:id |
PUT | Update a task. |
/api/tasks/:id |
DELETE | Delete a task. |
/api/graphql |
POST | Perform a GraphQL query. |
/api/notifications |
POST | Send a real-time notification. |
/api/search |
POST | Search for expenses using Elasticsearch. |
Additionally, the root / endpoint provides a welcome message and information about the API.
More endpoints and features are available in the API. Refer to the Swagger documentation for detailed information.
| Field | Type | Description |
|ββββ-|βββ-|ββββββββββ|
| username | String | Unique username. |
| email | String | Unique email address. |
| password | String | Hashed password. |
| createdAt | Date | User creation date. |
| Field | Type | Description |
|ββββ-|βββ-|ββββββββββ|
| name | String | Budget name. |
| limit | Number | Budget limit. |
| createdAt | Date | Budget creation date. |
| Field | Type | Description |
|βββββ|βββ-|ββββββββββ|
| budgetId | String | ID of the associated budget. |
| description | String | Expense description. |
| amount | Number | Expense amount. |
| createdAt | Date | Expense creation date. |
| Field | Type | Description |
|βββββ|βββ-|βββββββββββ|
| customerId | String | ID of the associated customer. |
| amount | Number | Order amount. |
| status | String | Order status. |
| createdAt | Date | Order creation date. |
| Field | Type | Description |
|ββββ-|βββ-|ββββββββββ|
| name | String | Customer name. |
| email | String | Customer email address. |
| phone | String | Customer phone number. |
| Field | Type | Description |
|---|---|---|
description |
String | Task description. |
status |
String | Task status. |
createdAt |
Date | Task creation date. |
npm start
http://localhost:3000/graphql./api/notifications endpoint or CLI.docker-compose up --build
/api/search/expenses.budget-manager CLI to add tasks.localhost:9092.redis://localhost:6379.postgres://user:password@localhost:5432/budget_manager.mongodb://localhost:27017/budget_manager.nginx directory.kubernetes directory.kubectl apply -f kubernetes/
prometheus.yml.The Budget Management API interacts with various services and databases to provide a comprehensive backend solution. The architecture includes a frontend UI, a CLI tool, an API gateway, a gRPC server, and multiple external services. Here is a high-level overview of the service interaction:
flowchart LR
FE[Frontend UI<br/>]
CLI[CLI Tool / gRPC Clients]
APIGW[API Gateway / Express.js]
GRPC[gRPC Server]
CORE[Application Core<br/>Controllers & Services]
Mongo[MongoDB]
Postgres[PostgreSQL]
Elastic[Elasticsearch]
Redis[Redis Cache]
Queue[RabbitMQ / Kafka Queue]
Stream[Kafka Event Streaming]
External[External Services<br/>Email, SMS, etc.]
FE -->|HTTP / GraphQL requests| APIGW
CLI -->|CLI commands / gRPC calls| GRPC
APIGW <--> GRPC
APIGW -->|REST / WebSocket / GraphQL| CORE
GRPC --> CORE
CORE --> Mongo
CORE --> Postgres
CORE --> Elastic
CORE --> Redis
CORE --> Queue
CORE --> Stream
Queue -->|Asynchronous tasks| External
Stream -->|Event-driven actions| External
Ensure your .env file looks like this before getting started:
# Server Configuration
PORT=
# MongoDB Configuration
MONGO_DB_URI=
MONGO_DB_USERNAME=
MONGO_DB_PASSWORD=
# Redis Configuration
REDIS_HOST=
REDIS_PORT=
REDIS_URL=
# RabbitMQ Configuration
RABBIT_MQ_HOST=
RABBITMQ_URL=
# Kafka Configuration
KAFKA_BROKER=
# JWT Secret Key
JWT_SECRET=
# Elasticsearch Configuration
ELASTIC_SEARCH_URL=
# PostgreSQL Configuration
POSTGRES_URL=
The budget-manager CLI provides a convenient way to interact with the application from the command line.
Follow these steps to use the CLI:
npm link
budget-manager seed
budget-manager notify "Hello!"
budget-manager add-task "Task description"
budget-manager --help
This will display a list of available commands and options:
budget-manager --help
Usage: budget-manager [options] [command]
A CLI for managing budgets, tasks, orders, and more.
Options:
-V, --version output the version number
-h, --help display help for command
Commands:
seed Seed the MongoDB database with initial data
notify <message> Send a real-time notification to WebSocket clients
list-budgets List all budgets in the database
add-task <description> Add a new task to the task queue
list-orders List all orders in the database
add-order <customerId> <amount> Add a new order
list-customers List all customers in the database
add-customer <name> <email> [phone] Add a new customer
search-expenses <query> Search for expenses using a query
graphql-query <query> Perform a GraphQL query
help [command] display help for command
Examples:
$ budget-manager seed
$ budget-manager notify "Hello World!"
$ budget-manager list-budgets
$ budget-manager add-task "New Task Description"
budget-manager --version
The CLI provides a simple way to interact with the backend API and perform various operations. It can be used for testing, debugging, and managing the application without a frontend interface or using the Swagger documentation.
The Budget Management API includes a demo frontend UI for interacting with the backend.
It gives developers an idea of how the API can be used in a real-world application. The frontend UI is built using React, Redux, and Material-UI components.
To run the frontend UI, follow these steps:
frontend directory:
cd frontend
npm install --legacy-peer-deps if you encounter peer dependency issues)
npm install
npm start
http://localhost:3001 (or whichever port is specified in the console).Alternatively, it is also deployed live at https://budget-manage-app.vercel.app. Feel free to use the live version for testing and exploration.
For more information, refer to the Frontend README in the frontend directory to learn about the frontend UI components, features, and usage.
Here are some screenshots of the frontend UI:
Home:
Dashboard:
Budgets:
Expenses:
Profile:
Login:
Register:
Forgot Password:
Users:
/docs.
http://localhost:3000/api/graphql.
query {
budgets {
id
name
limit
createdAt
}
}
Or:
query {
expenses(budgetId: "64c9f8f2a73c2f001b3c68f4") {
id
description
amount
budgetId
createdAt
}
}
When you run these queries, you will receive a response with the requested data. GraphQL provides a flexible and efficient way to fetch and manipulate data from the backend. Here is an example:
nginx directory contains an Nginx configuration for reverse proxy and load balancing.server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
The Budget Management API includes support for gRPC to enable high-performance remote procedure calls.
node grpcServer.js
node grpcClient.js
.proto file for defining gRPC services and messages is located in the protos directory.Thatβs it! Your gRPC server and client should now be operational. π
The Budget Management API can be run in a Docker container for easy deployment and scaling.
You can build and run the app using Docker Compose:
docker-compose up --build
The Budget Management API now supports advanced deployment strategies for production-grade deployments:
# Deploy blue and green environments
kubectl apply -f kubernetes/backend-deployment-blue.yaml
kubectl apply -f kubernetes/backend-deployment-green.yaml
kubectl apply -f kubernetes/frontend-deployment-blue.yaml
kubectl apply -f kubernetes/frontend-deployment-green.yaml
# Deploy services
kubectl apply -f kubernetes/backend-service-blue-green.yaml
kubectl apply -f kubernetes/frontend-service-blue-green.yaml
# Apply production-ready configurations
kubectl apply -f kubernetes/hpa.yaml
kubectl apply -f kubernetes/pdb.yaml
kubectl apply -f kubernetes/network-policy.yaml
kubectl apply -f kubernetes/ingress.yaml
kubectl apply -f kubernetes/servicemonitor.yaml
# Switch traffic (after validation)
kubectl patch service backend-service -p '{"spec":{"selector":{"version":"green"}}}'
# Deploy stable version (90% traffic)
kubectl apply -f kubernetes/backend-deployment-canary-stable.yaml
kubectl apply -f kubernetes/frontend-deployment-canary-stable.yaml
# Deploy canary version (10% traffic)
kubectl apply -f kubernetes/backend-deployment-canary.yaml
kubectl apply -f kubernetes/frontend-deployment-canary.yaml
# Deploy services
kubectl apply -f kubernetes/backend-service-canary.yaml
kubectl apply -f kubernetes/frontend-service-canary.yaml
# Apply production-ready configurations
kubectl apply -f kubernetes/hpa.yaml
kubectl apply -f kubernetes/pdb.yaml
kubectl apply -f kubernetes/network-policy.yaml
For detailed deployment procedures and best practices, see:
Access metrics at:
http://backend-service:3000/metricshttp://frontend-service:3001/metricsView health endpoints:
http://backend-service:3000/healthhttp://backend-service:3000/readyThere is also a Spring Boot Java version of the Budget Management API available in the spring-boot directory. It is built using Maven and Gradle.
To run the Spring Boot Maven application, follow these steps:
spring-boot directory:
cd spring
mvn clean install
mvn spring-boot:run
http://localhost:8080.To run the Spring Boot Gradle application, follow these steps:
spring-boot directory:
cd gradle
./gradlew build
./gradlew bootRun
http://localhost:8080.There is also a Dotnet C# version of the Budget Management API available in the dotnet directory. It is built using ASP.NET Core.
To run the Dotnet C# application, follow these steps:
dotnet directory:
cd dotnet
dotnet build
dotnet run
http://localhost:5000.The Budget Management API includes an advanced Jenkins pipeline with support for multiple deployment strategies and production-ready features.
Configure the pipeline with these parameters:
rolling, blue-green, or canarystaging or productionDEPLOYMENT_STRATEGY: blue-green
ENVIRONMENT: production
RUN_SMOKE_TESTS: true
AUTO_ROLLBACK: true
DEPLOYMENT_STRATEGY: canary
ENVIRONMENT: production
CANARY_PERCENTAGE: 10
RUN_SMOKE_TESTS: true
AUTO_ROLLBACK: true
DEPLOYMENT_STRATEGY: rolling
ENVIRONMENT: staging
RUN_SMOKE_TESTS: true
AUTO_ROLLBACK: true
docker-registry-credentials: Docker registry username/passwordkubeconfig-credentials: Kubernetes configuration fileslack-webhook: Slack webhook URL for notificationshttp://jenkins-server/github-webhook/deploy-{commit-sha}The Jenkinsfile includes sophisticated deployment functions:
deployRolling(): Executes rolling deployment strategydeployBlueGreen(): Manages blue-green deployment with traffic switchingdeployCanary(): Handles canary deployment with gradual rolloutvalidateDeployment(): Validates new deployment healthvalidateCanaryHealth(): Checks canary deployment healthperformRollback(): Automatic rollback to previous versionsendNotification(): Sends Slack notifications for pipeline eventsFor detailed deployment procedures, see Deployment Guide.
The Budget Management API also includes a GitHub Actions workflow for continuous integration and deployment.
.github/workflows/ci.yml file defines the CI/CD workflow, including steps for checking out code, installing dependencies, running tests, and building the application.main branch.npm test to ensure all tests pass before proceeding to the build or deployment stages.This setup allows for automated testing and deployment, ensuring that the application is always in a deployable state.
The Budget Management API includes unit tests for all endpoints and services.
To run the tests, use the following command:
npm test
The test results will be displayed in the console.
Watch Mode: To run tests in watch mode, which automatically re-runs tests on file changes, use:
npm test:watch
Coverage Report: To generate a code coverage report, use:
npm test:coverage
Mocha and Chai tests: In addition to the Jest tests, the project also includes Mocha and Chai tests for the application. These tests can be run using:
npm run test:mocha
Contributions are welcome! Please fork the repository, create a feature branch, and submit a pull request:
git checkout -b feature-branch).git commit -am 'Add new feature').git push origin feature-branch).This project is built with β€οΈ by:
For more information about me, you can visit my personal website or connect with me on LinkedIn:
Feel free to reach out if you have any questions or feedback! π
Thank you for using the Budget Management API. For questions, feedback, or support, please open an issue or contact me directly.
Created with β€οΈ by Son Nguyen in 2024. All rights reserved.