A robust URL shortening service (URLS) built with Node.js, Express, and MongoDB.
- Node.js (v14 or higher)
- MongoDB (v4.4 or higher)
- npm or yarn
- Clone the repository:
git clone https://github.com/xyberty/urls.git
cd urls- Install dependencies:
npm install- Create a
.envfile in the root directory:
NODE_ENV=development
PORT=3000
DB_URL=mongodb://localhost:27017/urlshortener
LOG_LEVEL=info- Start the server:
npm start- Docker
- Docker Compose
The easiest way to run the application with Docker is using Docker Compose, which will set up both the application and MongoDB:
- Build and start the containers:
docker-compose up -d- View logs:
docker-compose logs -f app- Stop the containers:
docker-compose down- Stop and remove volumes (this will delete MongoDB data):
docker-compose down -vThe application will be available at http://localhost:3000.
You can customize the Docker setup by setting environment variables:
SESSION_SECRET: Secret key for session management (default:change-this-secret-in-production)PORT: Application port (default:3000)DB_URL: MongoDB connection string (default:mongodb://mongo:27017/urlshortener)DB_NAME: Database name (default:urlshortener)
You can set these in a .env file or directly in docker-compose.yml.
To build the Docker image without Docker Compose:
docker build -t urls-app .To run the container:
docker run -p 3000:3000 \
-e DB_URL=mongodb://your-mongo-host:27017/urlshortener \
-e SESSION_SECRET=your-secret-key \
urls-appNote: When running manually, ensure MongoDB is accessible from the container or use the file storage fallback.
- POST
/shortUrls- Body:
fullUrl(required): Original URL to shortencustomSuffix(optional): Custom alias for the URL
- Response: Redirects to homepage with new short URL
- Body:
- GET
/:shortUrl- Params:
shortUrl: Short URL or custom alias
- Response: Redirects to original URL
- Params:
- GET
/health- Response: Basic health status
- GET
/health/detailed- Response: Detailed health information
NODE_ENV: Application environment (development/production)PORT: Server portDB_URL: MongoDB connection stringLOG_LEVEL: Logging level (error/warn/info/debug)
npm start: Start the servernpm test: Run testsnpm run dev: Start with nodemon for development
project-root/ ├── config/ │ └── config.js # Environment configurations ├── middleware/ │ ├── rateLimiter.js # Rate limiting configuration │ └── urlValidator.js # URL validation middleware ├── utils/ │ ├── errorHandler.js # Centralized error handling │ ├── logger.js # Winston logger configuration │ └── monitoring.js # Application monitoring ├── tests/ │ └── shortUrl.test.js # Unit tests ├── jest.config.js # Jest testing configuration ├── server.js # Main application file └── shortUrl.js # URL model definition
The application includes built-in monitoring and error handling:
- Memory usage monitoring (logs every 5 minutes)
- Unhandled rejection tracking
- Uncaught exception handling
- Structured error responses
- Production/Development specific error details
Run the test suite:
npm testTo run tests with coverage report:
npm test -- --coverageThe API returns structured error responses:
{
"status": "error",
"error": {...},
"message": "Error description",
"stack": "Error stack trace"
}{
"status": "error",
"message": "User-friendly error message"
}The API implements rate limiting with the following defaults:
- Development: 100 requests per 15 minutes
- Production: 50 requests per 15 minutes
The application logs important metrics:
- Memory usage
- Unhandled rejections
- Uncaught exceptions
- Database connection status
- Application errors
Logs are stored in:
logs/error.log- Error-level logslogs/combined.log- All logs