Сервис принимает оригинальные адреса и генерирует из них короткие. При переходе на короткий адрес - перенаправляет пользователя на оригинальный URL и собирает статистику по переходам: кто перешёл, когда, с какого устройства и браузера.
- UI - http://localhost:8080/v1/web
- Документация API - Swagger - http://localhost:8080/swagger
- Конфиг - config/config.go. Читается из
.envфайла. - Логгер - pkg/logger/logger.go. Интерфейс позволяет подменить логгер.
- Кеширование популярных ссылок (Redis) - internal/repo/cache/link_redis.go.
- Удобная и гибкая конфигурация HTTP сервера - pkg/httpserver/options.go.
Позволяет конфигурировать сервер в конструкторе таким образом:
Аналогичный подход с таким конфигурированием в пакете pkg/redis
httpServer := httpserver.New(httpserver.Port(cfg.HTTP.Port))
- В слое контроллеров применяется версионирование - internal/controller/restapi/v1.
Для версии v2 нужно будет просто добавить папку
restapi/v2с таким же содержимым, в файле internal/controller/restapi/router.go добавить строку:
{
v1.NewLinkRoutes(apiV1Group, lk, l, baseURL+"/v1")
}
{
v2.NewLinkRoutes(apiV1Group, lk, l, baseURL+"/v2")
}- Graceful shutdown - internal/app/app.go.
- Клонируйте репозиторий
- В корне создайте
.envфайл, скопируйте туда содержимое env.example -cp .env.example .env - Выполните, дождитесь запуска сервиса
make compose-up - Перейдите на http://localhost:8080/v1/web и пользуйтесь сервисом.
request:
{
"url": "https://www.rbc.ru/person/680a00fa9a79477f2728e7a2",
"custom_alias": "messi"
}response:
{
"original_url": "https://www.rbc.ru/person/680a00fa9a79477f2728e7a2",
"short_url": "http://localhost:8080/v1/s/messi"
}request:
GET http://localhost:8080/v1/s/messi
response: 301 redirect
request:
GET http://localhost:8080/v1/analytics/messi
response:
{
"analytics": {
"total_clicks": 12,
"clicks_by_browser": [
{
"browser": "Firefox",
"clicks": 5
},
{
"browser": "Chrome",
"clicks": 7
}
],
"clicks_by_device": [
{
"device": "Desktop",
"clicks": 7
},
{
"device": "Mobile",
"clicks": 5
}
],
"recent_clicks": [
{
"date": "2026-01-30",
"clicks": 7
},
{
"date": "2026-01-29",
"clicks": 5
}
]
}
}request:
GET http://localhost:8080/v1/analytics/messi?group-by=day
response:
{
"analytics": {
"recent_clicks": [
{
"date": "2026-01-30",
"clicks": 7
},
{
"date": "2026-01-29",
"clicks": 5
}
]
}
}request:
GET http://localhost:8080/v1/analytics/messi?group-by=month
response:
{
"analytics": {
"recent_clicks": [
{
"date": "2026-01",
"clicks": 12
}
]
}
}request:
GET http://localhost:8080/v1/analytics/messi?group-by=browser
response:
{
"analytics": {
"clicks_by_browser": [
{
"browser": "Firefox",
"clicks": 7
},
{
"browser": "Chrome",
"clicks": 5
}
]
}
}request:
GET http://localhost:8080/v1/analytics/messi?group-by=device
response:
{
"analytics": {
"clicks_by_device": [
{
"device": "Desktop",
"clicks": 7
},
{
"device": "Mobile",
"clicks": 5
}
]
}
}Зависимости:
make deps
docker compose down -v:
make compose-down