This repository contains an alias generator and an API for URL shortening. Alias generator is a worker service that generates aliases on demand. The API provides a way to shorten URLs with either a user provided or generated alias. It also provides redirects to the original URL by alias.
Project structure is organized by Clean Architecture Solution Template.
- Database: Apache Cassandra (NoSQL)
- Messaging: Apache Kafka
The setup for running the solution locally is intended to be flexible and aimed for a real-world application. To run the API and/or the alias generator, you need to have your infrastructure running. Listed below are the steps on how to do it:
- Create a docker bridge network
- Start Cassandra cluster
- Run database migrations
- Start Kafka ZooKeeper and Broker
- Create Kafka topic
To run the generator and the API:
Finally, to clean up:
Run the following commands from the root of the repository:
Creates a docker bridge network for our application.
docker network create url-shortener-network
Please note that it takes a while for Cassandra nodes to initialize.
docker run --rm -d -p 9042:9042 --name cassandra-node1 --network url-shortener-network cassandra:4.0.6
docker run --rm -d --name cassandra-node2 --network url-shortener-network -e CASSANDRA_SEEDS=cassandra-node1 cassandra:4.0.6
Please note that migrations will fail if Cassandra nodes are not initialized.
docker build --tag cassandra-migrate migrations
docker run --rm -it -v %cd%/migrations:/migrations --network url-shortener-network cassandra-migrate cassandra-migrate -H host.docker.internal -c migrations/config.yml migrate
docker run --rm -d --name zookeeper --network url-shortener-network -e "ZOOKEEPER_CLIENT_PORT=2181" -e "ZOOKEEPER_TICK_TIME=2000" confluentinc/cp-zookeeper:7.0.0
docker run --rm -d --name broker --network url-shortener-network -p 9092:9092 -e "KAFKA_BROKER_ID=1" -e "KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181" -e "KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_INTERNAL:PLAINTEXT" -e "KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://host.docker.internal:9092,PLAINTEXT_INTERNAL://broker:29092" -e "KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1" -e "KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=1" -e "KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=1" confluentinc/cp-kafka:7.0.0
Creates alias_candidates topic. Alias generator will publish messages to it and API will consume them.
docker exec broker kafka-topics --create --topic alias_candidates --bootstrap-server host.docker.internal:9092 --replication-factor 1 --partitions 1
docker build -f Generator/Generator.Worker/Dockerfile -t url-shortener-generator .
docker run --rm -d --network url-shortener-network -e "DOTNET_ENVIRONMENT=Development" --name url-shortener-generator url-shortener-generator
docker build -f Api/UrlShortener.Api/Dockerfile -t url-shortener-api .
docker run --rm -d --network url-shortener-network -e "ASPNETCORE_ENVIRONMENT=Development" -e "ASPNETCORE_URLS=http://+:80" -p 9889:80/tcp --name url-shortener-api url-shortener-api
If all is well, you should be able to access the API at http://localhost:9889/swagger/index.html
docker kill cassandra-node1
docker kill cassandra-node2
docker kill zookeeper
docker kill broker
docker kill url-shortener-api
docker kill url-shortener-generator
- Resilience policies
- Authentication
- Optimize alias generation in batches, etc
- Cache
- CORS check
- API versioning, validation
- More application services in controllers (?)
- Alias expiration - cleanup expired links
- Users
- Port exposure for other Cassandra nodes on the same machine
- Access modifiers