Какой HTTP статус код должен возвращать сервис при редиректе по короткой ссылке
Что проверяют
Это вопрос из задачи на проектирование сокращателя ссылок. Интервьюер хочет услышать не номер кода, а понимание, как выбор влияет на кеширование в браузере, аналитику кликов и возможность поменять ссылку. Следом спросят про нагрузку и хранение.
Как отвечать
Коды редиректа различаются по двум признакам: постоянный или временный и сохраняет ли клиент метод запроса.
- 301 Moved Permanently: постоянный. Браузер кеширует его агрессивно и следующий переход делает сам, не заходя на ваш сервис;
- 302 Found: временный, каждый клик проходит через сервис;
- 307 и 308: временный и постоянный варианты, которые гарантированно сохраняют метод и тело. Для коротких ссылок, где всегда
GET, разница с 302 и 301 несущественна.
Дальше выбор под требования. Если продукту нужны статистика кликов, смена адреса назначения, блокировка вредоносных ссылок и срок жизни, отдавайте 302 (или 307), иначе браузер после первого перехода перестанет к вам приходить. 301 снижает нагрузку, но у тех, кто уже переходил по ссылке, поменять её фактически нельзя. Компромисс: 301 с Cache-Control: max-age на ограниченное время.
В Go это пара строк: маршрут GET /{code} на http.ServeMux (Go 1.22 и новее), код из r.PathValue("code"), поиск в кеше перед базой, затем http.Redirect(w, r, target, http.StatusFound). Событие клика отправляйте асинхронно, в канал или очередь, чтобы запись статистики не задерживала редирект. Неизвестный код это 404, удалённая или истёкшая ссылка 410 Gone.
Где спотыкаются
Выбирают 301 «потому что ссылка вечная» и тут же обещают считать клики. Повторные переходы из того же браузера до сервиса не дойдут.
Не валидируют целевой адрес при создании. Сервис превращается в открытый редирект для фишинга, а схему javascript: принимать нельзя вовсе, только http и https.
Пишут статистику синхронно в базу на каждый клик. Под нагрузкой редирект начинает тормозить из-за записи, которая пользователю не нужна.