USB - URL Shortener Backend
Table of Contents
This project is the part of my application to Joor company. Please, see the description of requirements below.
These are the business rules that need to be fulfilled:
-
User should be able to submit any URL and get a standardized, shortened URL back
-
User should be able to configure a shortened URL to redirect to different targets based on the device type (mobile, tablet, desktop) of the user navigating to the shortened URL
-
Navigating to a shortened URL should redirect to the appropriate target URL
-
User should be able to retrieve a list of all existing shortened URLs, including time since creation and target URLs (each with number of redirects)
-
API requests and responses should be JSON formatted.
-
Write tests to prove functionality.
These are some guidelines for scope and technology choice:
-
Don't worry about any user registration or authentication.
-
Use PHP, Python, or JavaScript with whatever web framework you prefer.
-
Use a relational database; I recommend SQLite for ease of use.
-
Please share this via a Github repository that we can clone.
-
Please provide instructions to set up, test and run the API in a local environment on Linux or Mac in a README file.
-
Building a front-end client for this API is not part of the assignment.
-
Deploying this API is not part of the assignment.
This projects requires you to have:
- git;
- Python>=3.6;
- virtualenv.
Clone the repository:
git clone git@github.com:dizpers/usb.git
Go to the project directory:
cd usb
Create virtual environment. Following command will create it in .env
directory with python3
executable:
virtualenv -p python3 .env
Activate that environment. For bash it will be:
source .env/bin/activate
Install both product and development python dependencies:
pip install -U -r requirements.txt
pip install -U -r requirements-dev.txt
Create and the local settings file by copying the template:
mv usb/config/local.py.example usb/config/local.py
I recommend you to run full test suite to be sure that all is working fine:
nosetests
Create DB structures:
./manage.py createdb
From this moment you're ready to run the application. You can do it via manage command like this:
./manage.py runserver
This project is equipped with special management command. You can run it with one of the following commands (considering that you're in the project root directory right now):
python manage.py
./manage.py
Execution of that command will print you the list of available arguments and options. You can use following commands within management tool:
- createdb - creates the database with all necessary structures;
- dropdb - clean the database;
- runserver - run the server;
- shell - (i)python shell with the context of the application;
- show-urls - prints all the urls matching routes in the project.
Try to perform a redirect by given short URL, considering a device type.
- id - string, representing the identifier of the short URL (match this regexp
^[a-zA-Z0-9]{6,}$
).
None.
- 301 (Moved Permanently) - successful redirect;
- 404 (Not Found) - can't find any match for given id.
Actual redirect code (301 or whatever) can be set in settings. In case when short URL id was successfully found, you'll
get Location
header value set to target URL.
Get a list of all existing shortened URLs, including time since creation and target URLs (each with number of redirects).
None.
None.
- 200 (OK) - a list is successfully generated.
JSON object of the following structure is returned:
{"short1": [
{"type": "desktop", "url": "...", "redirects": 23, "datetime": ""}
{"type": "tablet", "url": "...", "redirects": 23, "datetime": ""}
{"type": "mobile", "url": "...", "redirects": 23, "datetime": ""}
],
"short2": []
}
where:
- short1, short2, ..., shortN - short URL;
- type - device type (one of the
desktop
,tablet
andmobile
); - url - long URL for current short URL and the device type;
- redirects - number of redirects for current long URL;
- datetime - datetime (in UNIX format with milliseconds) of long URL addition (when it was shortened)
Create new short link by given long URL.
None.
Request body follows JSON format and looks like this:
{"url": "..."}
where:
- url - long URL to be shortened.
- 200 (OK) - short URL successfully created.
Response body is following JSON format and looks like this:
{"url": "..."}
where:
- url - short URL.
Update the short link to specify links for some device type(s).
- id - string, representing the identifier of the short URL (match this regexp
^[a-zA-Z0-9]{6,}$
).
Request body follows JSON format and looks like this:
{"desktop": "..."}
or
{"mobile": "...", "desktop": "...", "tablet": "..."}
where:
- desktop - long URL for desktop device;
- tablet - long URL for tablet device;
- mobile - long URL for mobile device.
You must specify at least one of the parameters above (desktop
, tablet
or mobile
), in any order.
- 200 (OK) - update was successful;
- 404 (Not Found) - the short URL isn't found.
In both cases you will get empty JSON object in a body.
Please, make sure that while developing:
- you're using local settings file (
usb/config/local.py
); - you've already installed development requirements (
pip install -U -r requirements-dev.txt
).
You can run full test suite by executing following command:
nosetests