Deploy a URL shortener with custom domain support in just a few lines of code.
cdk-url-shortener
is an AWS CDK L3 construct that will create a URL shortener with custom domain support. The service uses nanoid to generate URL-friendly unique IDs and will retry if an ID collision occurs.
Additionally, you can enable DynamoDB streams to capture changes to items stored in the DynamoDB table.
Table of Contents
- Features
- Installation
- Usage
- Create your first short URL
- Documentation
- Supporting this project
- License
- 🚀 Easy to Start - One-liner code to have your own URL shortener.
- 🏢 Custom Domain - Bring your custom domain name that fits your brand.
- 📡 DynamoDB Streams - Capture table activity with DynamoDB Streams.
TypeScript/JavaScript
$ npm install @rayou/cdk-url-shortener
Python
$ pip install rayou.cdk-url-shortener
.Net
$ nuget install CDK.URLShortener
# See more: https://www.nuget.org/packages/CDK.URLShortener/
import { URLShortener } from '@rayou/cdk-url-shortener';
new URLShortener(this, 'myURLShortener');
import * as route53 from '@aws-cdk/aws-route53';
import * as acm from '@aws-cdk/aws-certificatemanager';
import { URLShortener } from '@rayou/cdk-url-shortener';
const zone = route53.HostedZone.fromLookup(this, 'HostedZone', {
domainName: 'mydomain.com',
});
// Optional, a DNS validated certificate will be created if not provided.
const certificate = acm.Certificate.fromCertificateArn(
this,
'Certificate',
'arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012',
);
new URLShortener(this, 'myURLShortener').addDomainName({
domainName: 'foo.mydomain.com',
zone,
certificate,
});
import * as route53 from '@aws-cdk/aws-route53';
import { URLShortener } from '@rayou/cdk-url-shortener';
const zone = route53.HostedZone.fromLookup(this, 'HostedZone', {
domainName: 'mydomain.com',
});
new URLShortener(this, 'myURLShortener')
.addDomainName({
domainName: 'foo.mydomain.com',
zone,
})
.addDomainName({
domainName: 'bar.mydomain.com',
zone,
});
import * as lambda from '@aws-cdk/aws-lambda';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
import * as lambdaEventSources from '@aws-cdk/aws-lambda-event-sources';
import { URLShortener } from '@rayou/cdk-url-shortener';
const table = new dynamodb.Table(this, 'Table', {
partitionKey: {
name: 'id',
type: dynamodb.AttributeType.STRING,
},
stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES,
});
new URLShortener(this, 'myURLShortener', {
dynamoTable: table,
});
const streamHandlerCode = `'use strict';
exports.handler = async (event) => {
console.log('Received event:', JSON.stringify(event, null, 2));
for (const record of event.Records) {
console.log(record.eventID);
console.log(record.eventName);
console.log('DynamoDB Record: %j', record.dynamodb);
}
console.log(\`Successfully processed \${event.Records.length} records.\`);
};`;
const lambdaFn = new lambda.Function(this, 'myStreamHandler', {
runtime: lambda.Runtime.NODEJS_12_X,
handler: 'index.handler',
code: lambda.Code.fromInline(streamHandlerCode),
});
lambdaFn.addEventSource(
new lambdaEventSources.DynamoEventSource(table, {
startingPosition: lambda.StartingPosition.LATEST,
}),
);
-
After the deployment, you'll see
ApiKeyURL
andApiEndpoint
in CDK Outputs, visitApiKeyURL
to get your API key.Outputs: stack.CustomDomainApiEndpointcc4157 = https://mydomain.com stack.myURLShortenerApiEndpoint47185311 = https://yrzxcvbafk.execute-api.us-west-2.amazonaws.com/prod/ stack.ApiKeyURL = https://console.aws.amazon.com/apigateway/home?#/api-keys/k2zxcvbafw6
-
Run this cURL command to create your first short URL, an
ID
will be returned in the response.$ curl https://{API_ENDPOINT} / -X POST \ -H 'content-type: application/json' \ -H 'x-api-key: {API_KEY}' \ -d '{ "url": "https://github.com/rayou/cdk-url-shortener" }' {"id":"LDkPh"}
-
Visit
https://{API_ENDPOINT}/{ID}
then you'll be redirected to the destination URL.$ curl -v https://{API_ENDPOINT}/{ID} # e.g. https://mydomain.com/LDkPh < HTTP/2 301 < content-type: text/html; charset=UTF-8 < content-length: 309 < location: https://github.com/rayou/cdk-url-shortener <!DOCTYPE html><html><head><meta charset="UTF-8" /><meta http-equiv="refresh" content="0;url=https://github.com/rayou/cdk-url-shortener" /><title>Redirecting to https://github.com/rayou/cdk-url-shortener</title></head><body>Redirecting to <a href="https://github.com/rayou/cdk-url-shortener">https://github.com/rayou/cdk-url-shortener</a>.</body></html>
See API.md.
HTTP REQUEST
POST /
HEADERS
Name | Value | Required |
---|---|---|
content-type |
application/json |
Required |
x-api-key |
Get your api key here | Required |
ARGUMENTS
Parameter | Type | Required | Description |
---|---|---|---|
url |
string | Required | Destination URL |
Example Request
curl https://mydomain.com /
-X POST \
-H 'content-type: application/json' \
-H 'x-api-key: v3rYsEcuRekey' \
-d '{
"url": "https://github.com/rayou/cdk-url-shortener"
}'
Response (201)
{
"id": "LDkPh"
}
HTTP REQUEST
GET /:id
Example Request
curl https://mydomain.com/:id
Response (301)
< HTTP/2 301
< content-type: text/html; charset=UTF-8
< content-length: 309
< location: https://github.com/rayou/cdk-url-shortener
<!DOCTYPE html><html><head><meta charset="UTF-8" /><meta http-equiv="refresh" content="0;url=https://github.com/rayou/cdk-url-shortener" /><title>Redirecting to https://github.com/rayou/cdk-url-shortener</title></head><body>Redirecting to <a href="https://github.com/rayou/cdk-url-shortener">https://github.com/rayou/cdk-url-shortener</a>.</body></html>
I'm working on this project in my free time, if you like my project, or found it helpful and would like to support me, you can buy me a coffee, any contributions are much appreciated! ❤️
This project is distributed under the Apache License, Version 2.0.