The trendy modern question for developer inteviews seems to be, "how to create an url shortner". Not wanting to fall too far from the cool kids, we have a challenge for you!
The challenge, if you choose to accept it, is to create a micro service to shorten urls, in the style that TinyURL and bit.ly made popular.
- The service must expose HTTP endpoints according to the definition below.
- The service must be self contained, you can use any language and technology you like, but it must be possible to set it up from a fresh install of Ubuntu Server 14.04, by following the steps you write in the README.
- It must be well tested, it must also be possible to run the entire test suit with a single command from the directory of your repository.
- The service must be versioned using git and submitted by making a Pull Request against this repository, git history should be meaningful.
- You don't have to use a datastore, you can have all data in memory, but we'd be more impressed if you do use one.
- Less is more, small is beautiful, you know the drill — stick to the requirements.
- Don't try to make the microservice play well with others, the system is all yours.
- No need to take care of domains, that's for a reverse proxy to handle.
- Unit tests > Integration tests, but be careful with untested parts of the system.
Good Luck! — not that you need any ;)
First of all You need to have Docker Engine and Docker up and running. Read manual if needed: Ubuntu install docs.
If you are running Production environment, create .env
file
# .env
RAILS_ENV=production
SECRET_KEY_BASE=<Make sure the secret is at least 30 characters and all random>
To start application you need to build images
$ docker-compose build
Create database and run migrations
$ docker-compose run api rake db:create db:migrate
Start service
$ docker-compose up
Running tests
$ docker-compose run -e RAILS_ENV=test api rake db:create db:migrate # if you haven't test database
$ docker-compose run api rspec
Using API
curl -X POST -i -H "Content-Type: application/json" \
-d '{ "url": "https://google.com", "shortcode": "google" }' \
"http://localhost:3000/shorten"
curl -X GET -i -H "Content-Type: application/json" \
"http://localhost:3000/google"
curl -X GET -i -H "Content-Type: application/json" \
"http://localhost:3000/google/stats"
All responses must be encoded in JSON and have the appropriate Content-Type header
POST /shorten
Content-Type: "application/json"
{
"url": "http://example.com",
"shortcode": "example"
}
Attribute | Description |
---|---|
url | url to shorten |
shortcode | preferential shortcode |
201 Created
Content-Type: "application/json"
{
"shortcode": :shortcode
}
A random shortcode is generated if none is requested, the generated short code has exactly 6 alpahnumeric characters and passes the following regexp: ^[0-9a-zA-Z_]{6}$
.
Error | Description |
---|---|
400 | url is not present |
409 | The the desired shortcode is already in use. Shortcodes are case-sensitive. |
422 | The shortcode fails to meet the following regexp: ^[0-9a-zA-Z_]{4,}$ . |
GET /:shortcode
Content-Type: "application/json"
Attribute | Description |
---|---|
shortcode | url encoded shortcode |
302 response with the location header pointing to the shortened URL
HTTP/1.1 302 Found
Location: http://www.example.com
Error | Description |
---|---|
404 | The shortcode cannot be found in the system |
GET /:code
Content-Type: "application/json"
Attribute | Description |
---|---|
shortcode | url encoded shortcode |
200 OK
Content-Type: "application/json"
{
"startDate": "2012-04-23T18:25:43.511Z",
"lastSeenDate": "2012-04-23T18:25:43.511Z",
"redirectCount": 1
}
Attribute | Description |
---|---|
startDate | date when the url was encoded, conformant to ISO8601 |
redirectCount | number of times the endpoint GET /shortcode was called |
lastSeenDate | date of the last time the a redirect was issued, not present if redirectCount == 0 |
Error | Description |
---|---|
404 | The shortcode cannot be found in the system |