A high-performance, feature-rich reverse proxy server built with Node.js and TypeScript, designed for load balancing, request routing, and traffic management.
- Load Balancing: Multiple algorithms (round-robin, least-connections, IP hash, random)
- Health Checking: Automatic upstream health monitoring with failover
- Request Routing: Flexible path-based routing with regex and parameter support
- Caching: Built-in response caching with configurable TTL
- Request/Response Transformation: Header manipulation and body transformation
- Redirection: Support for HTTP redirects and informational responses
- Worker Pool: Multi-process architecture for high concurrency
- YAML Configuration: Easy-to-use configuration system with validation
proxy-server/
├── dist/ # Compiled JavaScript output
├── node_modules/ # Dependencies
├── src/ # Source code
│ ├── config-schema.ts # Zod schemas for configuration validation
│ ├── config.ts # Configuration parsing and validation
│ ├── server-schema.ts # Worker message schemas
│ ├── server.ts # Main server implementation
│ ├── load-balancing.ts # Load balancing algorithms
│ ├── index.ts # CLI support
│ └── load-balancer-test.ts # Load balancer tests
├── .gitignore # Git ignore file
├── config.yaml # Main configuration file
├── package.json # Package dependencies and scripts
├── package-lock.json # Locked dependency versions
├── pnpage.json # Additional package configuration
└── README.md # This file
-
Clone the repository:
git clone https://github.com/Rishabh426/proxy-server cd proxy-server -
Install dependencies:
pnpm install
-
Build the project:
pnpm run dev
The proxy server uses a YAML configuration file (config.yaml) to define its behavior. Here's a complete example:
server:
listen: 3000
upstreams:
- id: "node1"
url: "jsonplaceholder.typicode.com"
- id: "node2"
url: "localhost:8081"
headers:
- key: "X-Forwarded-For"
value: "$ip"
- key: Authorization
value: 'Bearer xyz'
rules:
- path: /users
upstreams: ["node1"]
- path: /comments
upstreams: ["node1"]
- path: /todos
upstreams: ["node1"]listen: Port number to listen onworkers: Number of worker processes (defaults to CPU count)loadBalancing: Load balancing algorithm
id: Unique identifier for the upstreamurl: Backend server URL
path: Route pattern (supports wildcards and parameters)upstreams: List of upstream IDs to route toheaders: Custom headers to add
Headers support variable substitution:
$ip: Client IP address$host: Request host header$useragent: User-Agent header$method: HTTP method$path: Request path
npm start -- --config config.yaml
node dist/index.js --config config.yamlpnpm run dev -- --config config.yamlpnpm dlx ts-node src/load-balancer-test.tsThe proxy server automatically handles all HTTP methods and routes them according to your configuration. Some special behaviors:
Performs an actual HTTP redirect to the upstream server. The client's browser will show the upstream URL.
Master process is running
Master process: Worker node 0 started
Master process: Worker node 1 started
Reverse proxy running on port 3000
Upstream api-server status changed from unknown to healthy
Set the number of workers based on your CPU cores and expected load:
server:
workers: 4 # Typically CPU cores or CPU cores * 2Enable caching for frequently accessed, relatively static content:
rules:
- path: "/api/static/*"
cacheEnabled: true
cacheTtl: 3600 # 1 hourChoose the appropriate algorithm for your use case:
round-robin: Even distributionleast-connections: Route to least busy serverip-hash: Consistent routing per clientrandom: Simple random selection
The proxy server handles various error scenarios:
- Upstream Unavailable: Returns 502 Bad Gateway
- Route Not Found: Returns 404 Not Found
- Internal Errors: Returns 500 Internal Server Error
- Create feature module in
src/ - Add configuration schema in
config-schema.ts - Update server implementation in
server.ts - Add tests in appropriate test file
- Update documentation
commander: CLI argument parsingyaml: YAML configuration parsingzod: Runtime type validationpath-to-regexp: Advanced routing patterns
typescript: TypeScript compiler@types/node: Node.js type definitionsnodemon: Development auto-restart
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Update documentation
- Submit a pull request
For issues and questions:
- Check the documentation above
- Review configuration examples
- Check server logs for error details
- Open an issue on GitHub with:
- Configuration file
- Error logs
- Steps to reproduce
- WebSocket proxying support
- SSL/TLS termination
- Metrics and monitoring dashboard
- Plugin system for custom middleware
- Docker containerization
- Kubernetes integration
- gRPC proxying support