A scalable, and production-ready URL shortening service built with modern web technologies. This service provides a complete REST API for creating, managing, and tracking short URLs with comprehensive analytics and validation.
- π URL Shortening: Generate unique 6-character short codes for any valid URL
- β©οΈ URL Redirection: Retrieve and redirect to original URLs using short codes
- π Analytics: Track access count and view detailed statistics
- π CRUD Operations: Full Create, Read, Update, Delete functionality
- β Input Validation: Comprehensive URL validation with proper error handling
- π Logging: Centralized logging system for monitoring and debugging
- π‘οΈ Type Safety: Built with TypeScript for enhanced development experience
- ποΈ Clean Architecture: Modular design with separation of concerns
- π§ Environment Configuration: Secure configuration management
- π¦ Modern Dependencies: Latest stable versions of all packages
- π― Error Handling: Comprehensive error handling and validation
- β‘ Performance: Optimized database queries and efficient algorithms
- Node.js (v18 or higher)
- npm or yarn
- MongoDB (local instance or cloud service like MongoDB Atlas)
-
Clone the repository
git clone https://github.com/your-username/url-shortening-service.git cd url-shortening-service -
Install dependencies
npm install
-
Environment Setup
Create a
.envfile in the root directory:PORT=3000 MONGODB_URI=mongodb://localhost:27017/url-shortener
-
Start the application
# Development mode (with hot reload) npm run dev # Production mode npm run build npm start
The server will start on http://localhost:3000 (or your configured PORT).
http://localhost:3000
This API does not require authentication for basic operations.
Creates a new short URL from a provided long URL.
Endpoint: POST /shorten
Request Body:
{
"url": "https://www.example.com/very/long/url/that/needs/shortening"
}Success Response (201 Created):
{
"_id": "68b76e89a648a01be70cbc43",
"accessCount": 0,
"url": "https://www.example.com/very/long/url/that/needs/shortening",
"shortCode": "gZZBAU",
"createdAt": "2025-09-02T22:24:09.150Z",
"updatedAt": "2025-09-02T22:24:09.150Z",
"__v": 0
}Error Responses:
400 Bad Request- Invalid URL format or missing URL500 Internal Server Error- Server error
Retrieves the original URL and increments the access counter.
Endpoint: GET /shorten/:shortCode
Parameters:
shortCode(string, required) - The 6-character short code
Success Response (200 OK):
{
"_id": "68b76e89a648a01be70cbc43",
"accessCount": 1,
"url": "https://www.example.com/very/long/url/that/needs/shortening",
"shortCode": "gZZBAU",
"createdAt": "2025-09-02T22:24:09.150Z",
"updatedAt": "2025-09-02T22:24:13.604Z",
"__v": 0
}Error Responses:
404 Not Found- Short code not found400 Bad Request- Invalid short code format
Updates the original URL for an existing short code.
Endpoint: PUT /shorten/:shortCode
Parameters:
shortCode(string, required) - The 6-character short code
Request Body:
{
"url": "https://www.updated-example.com/new/url"
}Success Response (200 OK):
{
"_id": "68b76e89a648a01be70cbc43",
"accessCount": 1,
"url": "https://www.updated-example.com/new/url",
"shortCode": "gZZBAU",
"createdAt": "2025-09-02T22:24:09.150Z",
"updatedAt": "2025-09-02T22:24:23.774Z",
"__v": 0
}Error Responses:
400 Bad Request- Invalid URL format or missing URL404 Not Found- Short code not found
Deletes an existing short URL.
Endpoint: DELETE /shorten/:shortCode
Parameters:
shortCode(string, required) - The 6-character short code
Success Response (204 No Content):
No content returned
Error Responses:
404 Not Found- Short code not found
Retrieves detailed statistics for a short URL.
Endpoint: GET /shorten/:shortCode/stats
Parameters:
shortCode(string, required) - The 6-character short code
Success Response (200 OK):
{
"_id": "68b76e89a648a01be70cbc43",
"accessCount": 15,
"url": "https://www.example.com/very/long/url/that/needs/shortening",
"shortCode": "gZZBAU",
"createdAt": "2025-09-02T22:24:09.150Z",
"updatedAt": "2025-09-02T22:30:45.123Z",
"__v": 0
}Error Responses:
404 Not Found- Short code not found
src/
βββ app.ts # Express application setup and middleware
βββ index.ts # Application entry point and server startup
βββ controllers/ # Request handlers and business logic
β βββ shortUrl.controllers.ts
βββ services/ # Business logic and data processing
β βββ shortUrl.service.ts
βββ models/ # Database models and schemas
β βββ shortUrl.ts
βββ routes/ # API route definitions
β βββ shortUrl.routes.ts
βββ db/ # Database connection and configuration
β βββ connect.ts
βββ utils/ # Utility functions and helpers
βββ config.ts # Environment configuration
βββ generateShortCode.ts # Short code generation algorithm
βββ logger.ts # Centralized logging system
- Separation of Concerns: Clear separation between controllers, services, and models
- Dependency Injection: Services are injected into controllers for better testability
- Error Handling: Comprehensive error handling at all layers
- Validation: Input validation at both controller and model levels
- Logging: Structured logging throughout the application
- Node.js - JavaScript runtime environment
- Express.js - Fast, unopinionated web framework
- TypeScript - Type-safe JavaScript development
- MongoDB - NoSQL document database
- Mongoose - MongoDB object modeling for Node.js
- ESLint - Code linting and quality assurance
- Prettier - Code formatting
- Nodemon - Development server with hot reload
- ts-node - TypeScript execution for Node.js
- Validator.js - String validation library
- dotenv - Environment variable management
| Variable | Description | Default | Required |
|---|---|---|---|
PORT |
Server port number | 3000 |
No |
MONGODB_URI |
MongoDB connection string | - | Yes |
The ShortUrl model includes the following fields:
{
_id: ObjectId, // MongoDB document ID
url: string, // Original URL (required, validated)
shortCode: string, // 6-character unique short code
accessCount: number, // Number of times accessed (default: 0)
createdAt: Date, // Creation timestamp
updatedAt: Date // Last update timestamp
}# Build the application
npm run build
# Start the production server
npm startCreate a Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist/ ./dist/
EXPOSE 3000
CMD ["npm", "start"]- Set up MongoDB Atlas or a production MongoDB instance
- Configure environment variables
- Set up reverse proxy (nginx) if needed
- Configure SSL certificates
- Set up monitoring and logging
You can test the API using curl or any HTTP client:
# Create a short URL
curl -X POST http://localhost:3000/shorten \
-H "Content-Type: application/json" \
-d '{"url": "https://www.example.com"}'
# Retrieve original URL
curl http://localhost:3000/shorten/YOUR_SHORT_CODE
# Get statistics
curl http://localhost:3000/shorten/YOUR_SHORT_CODE/stats- Postman - GUI-based API testing
- Insomnia - Modern API client
- curl - Command-line HTTP client
- Thunder Client - VS Code extension
- Database Indexing: Short codes are indexed for fast lookups
- Connection Pooling: MongoDB connection pooling for better performance
- Error Handling: Graceful error handling prevents crashes
- Logging: Efficient logging without performance impact
- Validation: Fast client-side and server-side validation
- Input Validation: Comprehensive URL validation
- Error Handling: Secure error messages without information leakage
- Environment Variables: Sensitive data stored in environment variables
- Type Safety: TypeScript prevents many runtime errors
- Database Security: Mongoose provides protection against NoSQL injection
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow the existing code style
- Add tests for new features
- Update documentation as needed
- Ensure all tests pass
- Use meaningful commit messages
This project is licensed under the ISC License - see the LICENSE file for details.
- Built as part of the roadmap.sh Backend Projects
- Inspired by modern URL shortening services
- Thanks to the open-source community for the amazing tools