internal/app
Инкремент 9
Добавьте в сервис функциональность аутентификации пользователя.
Сервис должен:
- Выдавать пользователю симметрично подписанную куку, содержащую уникальный идентификатор пользователя, если такой куки не существует или она не проходит проверку подлинности.
- Иметь хендлер
GET /api/user/urls
, который сможет вернуть пользователю все когда-либо сокращённые им URL в формате:
[
{
"short_url": "https://...",
"original_url": "https://..."
}, "..."
]
- При отсутствии сокращённых пользователем URL хендлер должен отдавать HTTP-статус
204 No Content
.
Инкремент 10
- Добавьте в сервис функциональность подключения к базе данных. В качестве СУБД используйте PostgreSQL не ниже 10 версии.
- Добавьте в сервис хендлер
GET /ping
, который при запросе проверяет соединение с базой данных. При успешной проверке хендлер должен вернуть HTTP-статус 200 OK
, при неуспешной — 500 Internal Server Error
.
- Строка с адресом подключения к БД должна получаться из переменной окружения
DATABASE_DSN
или флага командной строки -d
.
Инкремент 11
Перепишите сервис так, чтобы СУБД PostgreSQL стала хранилищем сокращённых URL вместо текущей реализации.
Сервису нужно самостоятельно создать все необходимые таблицы в базе данных. Схема и формат хранения остаются на ваше усмотрение.
При отсутствии переменной окружения DATABASE_DSN
или флага командной строки -d
или при их пустых значениях вернитесь последовательно к:
- хранению сокращённых URL в файле при наличии соответствующей переменной окружения или флага командной строки;
- хранению сокращённых URL в памяти.
Инкремент 12
Задание для трека «Сервис сокращения URL»
Добавьте новый хендлер POST /api/shorten/batch
, принимающий в теле запроса множество URL для сокращения в формате:
[
{
"correlation_id": "<строковый идентификатор>",
"original_url": "<URL для сокращения>"
},
"..."
]
В качестве ответа хендлер должен возвращать данные в формате:
[
{
"correlation_id": "<строковый идентификатор из объекта запроса>",
"short_url": "<результирующий сокращённый URL>"
},
"..."
]
Инкремент 13
Сделайте в таблице базы данных с сокращёнными URL уникальный индекс для поля с исходным URL. Это позволит избавиться от дублирующих записей в базе данных.
При попытке пользователя сократить уже имеющийся в базе URL через хендлеры POST
/ и POST /api/shorten
сервис должен вернуть HTTP-статус 409 Conflict
, а в теле ответа — уже имеющийся сокращённый URL в правильном для хендлера формате.
Стратегии реализации:
Чтобы не проверять наличие оригинального URL в базе данных отдельным запросом, можно воспользоваться конструкцией INSERT ... ON CONFLICT
в PostgreSQL. Однако в таком случае придётся самостоятельно возвращать и проверять собственную ошибку.
Чтобы определить тип ошибки PostgreSQL, с которой завершился запрос, можно воспользоваться библиотекой github.com/jackc/pgerrcode
, в частности pgerrcode.UniqueViolation
. В таком случае придётся делать дополнительный запрос к хранилищу, чтобы определить сокращённый вариант URL.
Инкремент 14
Сделайте в таблице базы данных с сокращёнными URL дополнительное поле с флагом, указывающим на то, что URL должен считаться удалённым.
Далее добавьте в сервис новый асинхронный хендлер DELETE /api/user/urls
, который принимает список идентификаторов сокращённых URL для удаления в формате:
[ "a", "b", "c", "d", ...]
В случае успешного приёма запроса хендлер должен возвращать HTTP-статус 202 Accepted
. Фактический результат удаления может происходить позже — каким-либо образом оповещать пользователя об успешности или неуспешности не нужно.
Успешно удалить URL может пользователь, его создавший. При запросе удалённого URL с помощью хендлера GET /{id}
нужно вернуть статус 410 Gone
.
Совет:
- Для эффективного проставления флага удаления в базе данных используйте множественное обновление (batch update).
- Используйте паттерн
fanIn
для максимального наполнения буфера объектов обновления.