A URL shortening service built with NestJS, TypeScript, Nginx, Redis and PostgreSQL.
This API implements rate limiting to prevent abuse and ensure fair usage:
- Global limit: 100 requests per minute across all endpoints
- Authentication endpoints:
- Sign up: 3 requests per minute
- Sign in: 5 requests per minute
- URL management endpoints:
- Create short URL: 20 requests per minute
- Delete URL: 10 requests per minute
- Redirect endpoint: Exempt from rate limiting to ensure smooth redirection
Rate limits are implemented using NestJS Throttler module with Redis storage for different configurations for various route groups.
- Nginx
- NestJS
- TypeScript
- PostgreSQL
- Prisma ORM
- Redis
From a fresh clone:
git clone https://github.com/gregsyu/url-shortener.git
cd url-shortener
cp .env.example .envSet JWT_SECRET in .env:
JWT_SECRET="your-secret-key"
REDIS_URL="redis://redis:6379"
POSTGRES_USER="postgres"
POSTGRES_PASSWORD="postgres"
POSTGRES_DB="url_shortener"The Docker Compose file provides the container database URL automatically:
DATABASE_URL="postgresql://postgres:postgres@db:5432/url_shortener"docker compose build # build the app image
docker compose up -d db redis # start the databases
docker compose run --rm app pnpm prisma migrate deploy # run database migrations
docker compose up -d app nginx # start the application:For production, keep migrations separate from application startup this avoids running schema changes on every app restart and makes migration failures explicit during deployment.
Tip
You can also run Prisma Studio to visually manage your database:
docker compose up -d prisma-studioThen visit http://localhost:51212 to access Prisma Studio interface.
Note
The API will be available at http://localhost:8080.
To stop the containers:
docker compose down -vpnpm installCreate a .env file:
DATABASE_URL="postgresql://postgres:password@localhost:5432/url_shortener"
JWT_SECRET="your-secret-key"
REDIS_URL="redis://localhost:6379"Generate Prisma Client:
pnpm prisma generateApply the schema:
pnpm prisma db pushpnpm run start:devpnpm run build
pnpm run start:prod| Method | Route | Description |
|---|---|---|
| POST | /auth/signup |
Create account |
| POST | /auth/signin |
Login and receive JWT |
| GET | /auth/me |
Check authentication |
| Method | Route | Description |
|---|---|---|
| POST | /url |
Create short URL |
| GET | /:code |
Redirect to original URL |
| GET | /url/:code |
Get URL statistics |
| DELETE | /url/:code |
Delete URL |
Creating a short URL:
{
"id": "cmabc123xyz",
"code": "xY7kLm2",
"original": "https://google.com",
"clicks": 0,
"shortUrl": "http://localhost:8080/xY7kLm2"
}