GitHunt
MA

Malomalsky/url_shrt

Lightweight JSON API url shortener

URL-SH0RT - сокращатель ссылок на Flask/JSON API.

API размещено по адресу https://url-sh0rt.herokuapp.com (отключено, не вижу смысла платить больше). Авторизация не требуется.

Также есть UI в виде телеграм-бота https://t.me/url_sh0rt_bot (возможна нестабильная работа, хостится дома на Raspberry Pi.)


Установка и настройка. (локальный хостинг)

Для работы приложения необходим Python версии 3.x (протестировано на Python 3.7.2 и Python 3.8.5)

Скачайте и распакуйте архив:

git clone https://github.com/Malomalsky/url_shrt.git

cd url_shrt

Находясь в директории, рекомендуется активировать виртуальное окружение (опционально). Далее установите зависимости:

pip install -r requirements.txt

Следом необходимо создать базу данных:

python url_shortener/createdb.py

Приложение готово к работе! Запустите его командой (находясь в корневой директории проекта):

flask run

Доступные методы

Обязательный заголовок всех запросов - "Content-Type": "application/json". JSON API все-таки!

Схема JSON-объекта выглядит следующим образом:

{ 
  "id" : "", (Автоинкремент)
  "original_url" : "", 
  "custom_url": "", (Опционально, по дефолту - null; должно быть уникально)
  "short_url": "", (Автогенерация, длинна = 5 букв),
  "date_created": "" (Автогенерация)
}

Методы, предоставляемые API:

url method action Тело запроса
/add_link POST Добавляет ссылку в базу данных, возвращает JSON с сокращенной ссылкой и (если была введена) кастомной
  • "original_url" : валидная оригинальная ссылка (example.com)
  • "custom_url" (опционально) : желаемая кастомная ссылка, обычное слово по которому будет доступна оригинальная ссылка
/links GET Возвращает JSON-список со всеми обьектами. -
/links/<id> GET Возвращает JSON с определенным объектом (по id) -
/links/<id> PUT Обновление информации в БД (по id) "original_url", "short_url", "custom_url"
/links/<id> DELETE Удаление информации (по id) -

Важно - редирект на оригинальные URL происходит при обращении на имя хоста

hostname/<short|custom>,
где hostname - 
127.0.0.1:5000, если запущено локально; 
https://url-sh0rt.herokuapp.com - захосченный сервис

.

Примеры работы.

Демонстрация проводится на https://url-sh0rt.herokuapp.com

Если программа запущена локально - обращаться по 127.0.0.1:5000


Добавим валидную ссылку:

  • Метод - POST
  • URL - /add_link

Запрос:

curl --location --request POST 'https://url-sh0rt.herokuapp.com/add_link' \
--header 'Content-Type: application/json' \
--data-raw '{
    "original_url": "avito.ru"
}'

Ответ:

{
    "custom_url": null,
    "date_created": "2020-09-24T16:18:59.181662",
    "id": 2,
    "original_url": "https://avito.ru",
    "short_url": "SmuBD"
}

Попробуем добавить невалидную ссылку:

  • Метод - POST
  • URL - /add_link

Запрос:

curl --location --request POST 'https://url-sh0rt.herokuapp.com/add_link' \
--header 'Content-Type: application/json' \
--data-raw '{
   "original_url": "avito" 
}'

Ответ:

{
    "message": "Not valid URL. Try again."
}

Можно заметить, что если была введена валидная ссылка, сокращатель добавляет к ней 'https://'


Добавим валидную ссылку вместе с кастомной

  • Метод - POST
  • URL - /add_link

Запрос:

curl --location --request POST 'https://url-sh0rt.herokuapp.com/add_link' \
--header 'Content-Type: application/json' \
--data-raw '{
    "original_url": "avito.ru",
    "custom_url": "best-marketplace"
}'

Ответ:

{
    "custom_url": "best-marketplace",
    "date_created": "2020-09-24T16:16:41.195786",
    "id": 1,
    "original_url": "https://avito.ru",
    "short_url": "FoAgl"
}

Попробуйте перейти:


Внесем еще пару ссылок - для проверки PUT и DELETE - запросов:

{
    "custom_url": null,
    "date_created": "2020-09-24T16:24:35.876784",
    "id": 3,
    "original_url": "https://vk.com",
    "short_url": "ANjno"
}
{
    "custom_url": "search",
    "date_created": "2020-09-24T16:31:15.454145",
    "id": 4,
    "original_url": "https://yandex.ru",
    "short_url": "L91Zy"
}

Обновим информацию о vk.com. Добавим кастомное имя 'soc':

  • Метод - PUT
  • URL - /links/<id>

Запрос:

curl --location --request PUT 'https://url-sh0rt.herokuapp.com/links/3' \
--header 'Content-Type: application/json' \
--data-raw '{
    "custom_url": "soc"
}'

Ответ:

{
    "custom_url": "soc",
    "date_created": "2020-09-24T16:24:35.876784",
    "id": 3,
    "original_url": "https://vk.com",
    "short_url": "ANjno"
}

Кстати, если попытаться ввести неуникальное кастомное имя, программа вернет следующее сообщение:

{
    "message": "Entered custom URL already existed."
}

Удалим данные о vk.com

  • Метод - DELETE
  • URL - /links/<id>

Запрос:

curl --location --request DELETE 'https://url-sh0rt.herokuapp.com/links/3' \
--header 'Content-Type: application/json' \
--data-raw ''

Ответ:

{
    "custom_url": "soc",
    "date_created": "2020-09-24T16:24:35.876784",
    "id": 3,
    "original_url": "https://vk.com",
    "short_url": "ANjno"
}

После чего данная информация будет удалена из БД.

Технические моменты (и усложнения)

Генерация сокращенных ссылок.

Генерация сокращенной ссылки очень проста - с помощью пайтоновского модуля random! 5 случайных выборов (random.choices) из последовательности цифр, строчных и прописных букв английского алфавита. При этом, каждая короткая ссылка должна быть уникальной, что предусмотрено в коде.

Кастомные ссылки.

Добавить кастомную ссылку можно с помощью включения в POST-запрос поля "custom_url". После чего можно обратиться к ней как к сокращенной ссылке -

hostname/custom_url

Валидация URL.

Валидация введенных URL производится с помощью регулярных выражений. Валидными считаются URL формата example.com или http|s://example.com. В первом случае к URL будет автоматически добавлен протокол: 'https://'

Тесты.

Все тесты лежат тут. Метод - по возвращаемым кодам состояний и полям возвращаемого JSON.

Бесплатный хостинг.

Как было сказано выше, API размещено на heroku.com. Обращаться по https://url-sh0rt.herokuapp.com

Нагрузочное тестирование.

Тестировалось https://url-sh0rt.herokuapp.com

Тестирование было приведено при помощи плагина для heroku - loader.io.
Результаты тестирования:

UI

В качестве доступного и удобного UI была выбрана платформа Telegram. Код бота лежит тут.
Схема работы:

Сигнатура команды Описание
/post_orig <original_url> POST-запрос, добавляет URL в базу данных; <original_url>; возвращает готовую к работе укороченную ссылку ответным сообщением.
/post_custom <original_url> <custom_url> POST-запрос, добавляет оригинальный и кастомный URL в базу данных; возвращает готовую к работе укороченную и кастомную ссылкы ответным сообщением.
/get <id> GET-запрос, возвращает JSON-объект по запрашиваемому ID.

Ошибки и коды состояний.

  • Not valid URL - внсение невалидного URL (!= example.com & http|s://example.com)
  • Entered custom URL already existed - попытка внесения неуникально кастомного URL
  • 200 - при успешном GET
  • 302 - при успешном редиректе
  • 400 - при вводе невалидного URL, неуникального кастомного URL при POST; при попытке редиректа на несуществующие короткие/кастомные ссылки.
Malomalsky/url_shrt | GitHunt