Design a URL shortening service similar to TinyURL, with the following goals:
Functional Requirements:
- Given a URL, generate a shorter alias for it.
- When accessing a shorter alias, redirect to the original link.
Non-functional Requirements:
- Availability: The system must be highly available for URL redirection.
- Low Latency: The system should perform at low latency to provide a smooth user experience.
All services are managed on Docker using Docker-compose. The services include 1 web server, 2 API servers, 1 Zookeeper, 1 Redis, and 1 PostgreSQL.
For more details, refer to How to Run.
-
front: This directory contains the frontend code of the project. It has been developed using
React/Typescript
. It is containerized withNginx
to serve static content and assign requests to the backend services. -
back: This directory contains the backend code of the project. It has been developed using
Go
and other relevant tools. As the API service, the backend must operate alongside other services, such asPostgres
,Zookeeper
, andRedis
. -
dockerconfig: This directory stores Dockerfiles and config files of other required services, such as
Redis
andZookeeper
. These files will be used when launching docker-compose.
The system comprises different components:
- A web server is a
React
application withNginx
. - API server replicas that handle
REST/RPC
requests/responses, a unique ID generator, andBase62
. - A
Zookeeper
provides distributed synchronization and supports the unique ID generation by maintaining sequence range for each API server replica. - A database stores the mapping of long and short URLs.
PostgreSQL
was chosen to focus on the performance of the application layer, with storage performance considered a future enhancement. - Furthermore, frequent read requests are cached by
Redis
to reduce latency and boost response times.
- Clone the repository to your local machine.
- Ensure that the Docker is already installed and running.
- Create a
.env
file with the required settings (make gen.env
). - Run
make app.start
to wait for all containers to run. - Open the browser and go to
http://localhost
to see the frontend app.