Пишем сокращатель ссылок при помощи AWS Lambda за 2 часа
Для тех, кто хочет создать сокращатель ссылок, мы перевели подробное руководство по созданию URL-сокращателя при помощи AWS Lambda.
8К открытий8К показов
Рассказывает Ян Куи
Интересное требование возникло на работе, когда мы обсуждали потенциальную необходимость запуска собственного сокращателя URL, потому что механизм универсальных ссылок (в iOS 9 и выше) требует JSON-манифест на https://domain.com/apple-app-site-association
.
Поскольку ОС не следует переадресациям, этот манифест должен быть размещен в корневом домене URL-сокращателя.
Из-за ограничения на AppsFlyer он не может сокращать URL, когда в приложении настроены универсальные ссылки. Мы могли бы перейти на другого поставщика, но это означало бы большую нагрузку для клиентских приложений.
Возник вопрос «Стоит ли создавать свой сокращатель ссылок?», который затем плавно перешел в «Насколько тяжело создать расширяемый сокращатель ссылок в 2017 году?».
Оказалось, что совсем не трудно, так как на то, чтобы внедрить, протестировать и развернуть, у меня ушло менее двух часов.
Lambda во имя победы
Для нашего сокращателя нам необходимы следующие вещи:
- Конечная точка
GET/{shortUrl}
, которая будет перенаправлять на оригинальный URL. - Конечная точка
POST/
, которая будет принимать оригинальный URL и возвращать сокращенный. index.html
— страница, где каждый мог бы легко создать короткий URL.- Конечная точка
GET/apple-app-site-association
, которая обслуживает статичный JSON-ответ.
Все эти вещи могут быть достигнуты с помощью API Gateway и Lambda.
Прим. перев. Чтобы иметь представление о всём спектре сервисов, предоставляемых платформой Amazon Web Services (AWS), советуем прочитать нашу шпаргалку.
У меня получилась следующая структура проекта:
- используется шаблон
aws-nodejs
фреймворка Serverless; - каждая конечная точка имеет соответствующую функцию обработки;
- файл
index.html
в статичной папке; - тесты написаны таким образом, что могут использоваться как в качестве интеграционных тестов, так и в качестве приемочных;
- скрипт
build.sh
, облегчающий работу; - интеграционные тесты
./build.sh int-test {env} {region} {aws_profile}
; - приемочные тесты
./build.sh acceptance-test {env} {region} {aws_profile}
; - разворачивание
./build.sh deploy {env} {region} {aws_profile}
.
Конечная точка GET/apple-app-site-association
Так как JSON статичный, есть смысл вычислить HTTP-ответ заранее и возвращать его каждый раз:
Конечная точка POST/
Для алгоритма сокращения URL можно найти простое и элегантное решение на StackOverflow. Вам нужен только автоматически увеличивающийся ID, вроде того, что вы обычно получаете с помощью RDBMS.
Однако я заметил, что DynamoDB будет более подходящей базой данных по следующим причинам:
- это управляемый сервис, поэтому не надо волноваться об инфраструктуре;
- капитальные расходы лучше операционных;
- есть возможность масштабировать пропускную способность чтения и записи, чтобы соответствовать уровню использования и обрабатывать любые скачки трафика.
Но в DynamoDB нет такого понятия, как автоматически увеличивающийся ID, который необходим для алгоритма. Вместо него вы можете использовать атомарный счетчик для симуляции автоматического увеличения за счет дополнительной единицы записи за запрос.
Конечная точка GET/{shortUrl}
Как только мы установили соответствие в таблице DynamoDB, конечная точка перенаправления стала простым взятием оригинального URL и возвращением его как части заголовка Location.
И не забудьте возвращать соответствующий статусу код HTTP, в данном случае 308 (обязательное перенаправление).
Страница GET/index
Наконец, для страницы index
мы будем возвращать HTML (и другой тип контента вместе с HTML).
Я решил поместить HTML-файл в статичную папку, которая загружается и кэшируется в первый раз, когда вызывается функция.
Подготовка к работе
К счастью, у меня было много опыта работы с AWS Lambda, поэтому я знаю, что для URL-сокращателя нам необходимо:
- настроить автомасштабируемые параметры для таблицы DynamoDB (для которой у нас есть внутренняя система управления автоматическим масштабированием);
- включить кэширование для API Gateway на производственном уровне.
Будущие улучшения
Если поместить один и тот же URL несколько раз, то вы будете получать разные короткие ссылки. Для оптимизации нужно возвращать одну и ту же ссылку, используя кэш.
Чтобы это сделать, вы можете:
- Добавить GSI в таблице DynamoDB к
longUrl
для поддержки эффективного обратного поиска. - В функции
shortUrl
выполнять GET вместе с GSI для поиска существующих коротких URL.
Более подходящим вариантом будет добавление GSI, нежели создание новой таблицы. Это поможет избежать транзакций между несколькими таблицами.
8К открытий8К показов