This is a serverless URL shortener API built using AWS Lambda, API Gateway and DynamoDB. The API was built using FastAPI and Python, and it has only two endpoints as shown below:
One HTTP action to register new URLs, and returns the random shorten URL:
And another endpoint to resolve a given shortlink:
Amazon API Gateway is an AWS service for creating and securing REST APIs at any scale.
AWS Lambda is a serverless, event-driven compute service that allows one to run code without provisioning or managing servers.
DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability.
The folder structure was created by a blank CDK project created with cdk init
.
resources/layers/python
- directory where the CI/CD pipeline will use to build the lambda layer containing the project dependencies.
resources/shortener_app
- main directory containing the application code
resources/shortener_app/schemas.py
- Using the pydantic library, we model the expected request and validate urls formatting
resources/shortener_app/requirements.txt
- library dependencies used by the app
A GitHub Actions pipeline is defined in the file .github/workflows/pipeline.yml
.
We need to setup the following secrets and variables on GitHub to be injected in the pipeline:
- AWS_ACCESS_KEY_ID - AWS access key
- AWS_SECRET_ACCESS_KEY - AWS secret access key
- CUSTOM_DOMAIN - custom domain to be used by API Gateway
In order to deploy a custom domain name for our API in API Gateway, it was needed to create a few extra resources:
- The CDK stack needs to receive an pre-existing Route 53 Hosted Zone -- via GitHub Actions environment variable CUSTOM_DOMAIN
- A new ACM Certificate will be generated pointing to domain "api.CUSTOM_DOMAIN"
- A new Route53 record 'api' will be added to the CUSTOM_DOMAIN hosted zone
Without changing the functionality of the service, how to:
- For Lambda, we could raise a quota increase greater than the default 1000 request per all lambdas in one AWS Account.
- We could add Provisioned concurrency to the Lambda function, thus it would scale without fluctuations in latency.
- Adoption of SQS Queues betwen API Gateway and the Lambda Function. Optionally leverage StepFunctions to create serverless workflows with dead-letter queues.
- Setup edge-optimized API Gateway endpoints with a built-in CloudFront distribution to deliver content quickluy to global clients.
- Adoption of a cache service like Elasticache/Redis in order to cache responses for a given URL.
- DynamoDB Accelerator could help by adding in-memory acceleration to the DynamoDB table.
- Set up Lambda function timeout
- Set CloudWatch billing alarms to be alarmed for unexpected bursts
- We could use a Lambda function for authorization in API Gateway, which would validade a JWT token to allow access to protected APIs.
- We could use a Cognito user pool with the admin users and grant access to protected resources in API Gateway.
- We could use IAM authentication for the protected resources.
Optimize your repository to accommodate for these operational goals.