A small URL shortener built with Node.js, Express, and PostgreSQL.
Submit a long http or https URL, get back a short URL, then visit the short URL to redirect back to the original destination.
POST /shortencreates a short URLGET /:coderedirects a short code to the stored long URL- PostgreSQL storage with a committed
schema.sql - Random 6-character short codes using
A-Z,a-z, and0-9 - Duplicate short-code retry handling using the database
UNIQUEconstraint - URL validation with Node's built-in
URLparser - Only allows
http:andhttps:URLs - Rate limiting on
POST /shorten - Environment variables loaded with
dotenv - Configurable server port with
PORT - Configurable public base URL with
BASE_URL - Interactive CLI client in
app.js
- Node.js 18+
- npm
- PostgreSQL
npm installCreate a PostgreSQL database, then run:
psql your_database_name < schema.sqlCurrent schema:
CREATE TABLE IF NOT EXISTS url_mapping (
id SERIAL PRIMARY KEY,
long_url TEXT NOT NULL,
short_code TEXT NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Create a .env file in the project root:
DATABASE_URL=postgres://username:password@localhost:5432/your_database_name
BASE_URL=http://localhost:3000Development mode with auto-restart:
npm run devBasic start:
npm startStart the server first, then run:
node app.jsEnter a URL when prompted:
Enter your long URL: https://example.com/some/long/pathExample output:
{
"message": "URL shortened successfully",
"shortUrl": "http://localhost:3000/abc123"
}The CLI posts to:
${BASE_URL}/shortenSo BASE_URL must point to your running server.
POST /shorten
Content-Type: application/jsonRequest body:
{
"longUrl": "https://example.com/some/long/path"
}Success response:
{
"message": "URL shortened successfully",
"shortUrl": "http://localhost:3000/abc123"
}Invalid URL response:
{
"error": "Invalid URL"
}Server failure response:
{
"error": "Failed to shorten URL"
}Visit:
http://localhost:3000/abc123app.js/client -> POST /shorten -> server.js -> INSERT into url_mapping -> JSON shortUrl
browser -> GET /:code -> server.js -> SELECT from url_mapping -> redirect| File | Purpose |
|---|---|
server.js |
Express app, database connection, routes, rate limiter, short-code generation |
app.js |
Interactive CLI client |
schema.sql |
PostgreSQL schema |
- Same long URL can be shortened multiple times into different codes.
- Redirect errors are plain text, while
/shortenerrors are JSON. - Stored redirect targets are trusted after insertion; there is no re-validation before
res.redirect. - No click tracking, expiry, delete endpoint, metadata endpoint, custom aliases, tests, linter, or UI.
- Not production-ready without more security work, especially around redirect abuse, CORS, and headers.