POST /api/v1.0/originalurl
{"original_url": url, "suggested_url", "expiration_date": date}
returns
{"original_url": url, "concise_url": url, "creation_date": date, "expiration_date": date, "created_by": email_addr, "used_suggested_url": bool}
If any URLs are invalid, return 400 with details
If suggested_url is available (and acceptable), we use it as concise_url
Otherwise, we generate a unique concise_url and use it
GET /API/v1.0/url/{shorturl}
If present, returns 200 original_url
If not, returns 404
GET /API/v1.0/stat/{shorturl}
returns
{"original_url": url, "concise_url": url, "creation_date": date, "total_hits": int, "hits_last_hour": int, "hits_last_day": int, ...}
NoSQL solution will be fine because that will allow DB sharding
Table: ConciseUrl
shortenedUrl str -- Primary Key
originalUrl str -- Index
createdDate timestamp
createdBy email_address
expirationDate timestamp
used_suggested_url str
Table: UrlStats
shortenedUrl str -- Primary Key
createdDate timestamp
total_hits int
hits_last_hour int
hits_last_day int
We have a Load Balancer to distribute requests across multiple servers.
There is a URL Shortener Service that takes a full URL, checks if the provided URLs are valid, checks to see if it already exists and, if not, it creates a unique, new concise URL. It then returns the concise URL.
There is a URL Expander Service that takes a concise URL, looks to see if it exists and, if so, returns the original URL. If not, returns 404. This service will get the most traffic, so we'll want many redundant service nodes.
There is a Memcached cache that stores most recent URL expansions.
There is a DynamoDB database that stores our two database tables.
For Get Concise Url:
For Expand Concise Url:
For Get Concise Url, the URL Shortener Service does the following:
We choose a Load Balancer to provide redundancy across servers and to enable us to scale horizontally. Also, if our service gets big enough, we can shard the DB by Concise URL to improve performance
We use a NoSQL DB to support sharding (Cassandara)
We use a Cache to improve DB performance (Redis)
One challenge will be to deal with collisions when shortening a URL. We have multiple strategies including a fall-back approach to enable us to have both meaningful short URLs and guarantee of uniqueness
I expect the URL Expander Service will get the vast majority of requests, so sharding is a good approach to limit bottlenecks.