A fully serverless URL shortener built using AWS services. Users can enter a long URL and get a shortened link that redirects to the original URL.
- Frontend: HTML, CSS, JavaScript (hosted on S3)
- Backend: AWS Lambda (Python)
- API Layer: Amazon API Gateway (HTTP API)
- Database: Amazon DynamoDB
- Deployment: AWS CLI
- Generate short URLs instantly
- Redirect to original URL
- Copy-to-clipboard support
- Fully serverless architecture
- No authentication required (simple MVP)
-
User enters a long URL in the frontend
-
Frontend sends POST request to API Gateway
-
API Gateway triggers Lambda function
-
Lambda:
- Generates a random short ID
- Stores
{ shortId → longUrl }in DynamoDB
-
When user visits
/shortId:- Lambda fetches original URL
- Returns HTTP 302 redirect
URL_Shortener_Service/
│
├── Frontend/
│ ├── index.html # UI for URL shortening
│ └── policy.json # S3 bucket public access policy
│
├── Backend/
│ ├── lambda_function.py # AWS Lambda logic (Python)
│ ├── lambda-trust.json # IAM role trust policy
│ └── function.zip # Deployment package (generated)
│
├── README.md
- AWS Account
- AWS CLI installed & configured
- Basic knowledge of AWS services
aws s3 mb s3://your-bucket-name
aws s3 website s3://your-bucket-name \
--index-document index.htmlUpload frontend:
aws s3 cp Frontend/index.html s3://your-bucket-nameaws dynamodb create-table \
--table-name UrlTable \
--attribute-definitions AttributeName=shortId,AttributeType=S \
--key-schema AttributeName=shortId,KeyType=HASH \
--billing-mode PAY_PER_REQUESTZip your function:
zip function.zip lambda_function.pyCreate IAM role (Lambda execution role):
-
Attach:
- AmazonDynamoDBFullAccess
- AWSLambdaBasicExecutionRole
Create function:
aws lambda create-function \
--function-name UrlShortenerFunction \
--runtime python3.12 \
--role YOUR_ROLE_ARN \
--handler lambda_function.lambda_handler \
--zip-file fileb://function.zipaws apigatewayv2 create-api \
--name url-shortener-api \
--protocol-type HTTPCreate integration:
aws apigatewayv2 create-integration \
--api-id YOUR_API_ID \
--integration-type AWS_PROXY \
--integration-uri YOUR_LAMBDA_ARN \
--payload-format-version 2.0Create routes:
POST /shorten
GET /{id}Create stage:
aws apigatewayv2 create-stage \
--api-id YOUR_API_ID \
--stage-name prod \
--auto-deployaws lambda add-permission \
--function-name UrlShortenerFunction \
--statement-id apigateway-access \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:REGION:ACCOUNT_ID:API_ID/*/*"aws apigatewayv2 update-api \
--api-id YOUR_API_ID \
--cors-configuration 'AllowOrigins=["*"],AllowMethods=["GET","POST","OPTIONS"],AllowHeaders=["*"]'Update index.html:
const AWS_API_ENDPOINT = "https://YOUR_API_ID.execute-api.REGION.amazonaws.com/prod/shorten";Upload again:
aws s3 cp Frontend/index.html s3://your-bucket-namecurl -X POST "https://API_ID.execute-api.REGION.amazonaws.com/prod/shorten" \
-H "Content-Type: application/json" \
-d '{"url":"https://google.com"}'https://API_ID.execute-api.REGION.amazonaws.com/prod/{shortId}
- Do NOT commit AWS credentials
- Use IAM roles with least privilege
- Use GitHub Secrets for CI/CD
- Custom short URLs
- Click analytics
- Expiration links
- User authentication
- Custom domain (Route 53 + CloudFront)
Feel free to fork and deploy using your own AWS account.
This project is for learning purposes. All users must configure their own AWS credentials.
