Сервис для подачи объявлений
Как запустить
- Установить Docker и Docker-Compose
docker-compose build && docker-compose up -d
- Таблицы создаются через
gorm
внутриapp
, БД создается пустой.
API
Address: http://localhost:8888
Prefix: /api/v0.1
Endpoint | Method | Description |
---|---|---|
/ads |
POST |
Создание объявления |
/ads |
GET |
Получение списка объявлений(для пагинции) |
/ads/{id} |
GET |
Получение объявления |
Примеры использования
/create_ad
)
1. Создать объявление(Пример запроса:
curl POST -v -d "{
\"title\": \"Гараж\",
\"description\": \"Продам гараж\nТелефон:...\",
\"price\": 45999.99,
\"image_urls\": [\"photo.example.ru/img/1.png\", \"photo.example.ru/img/2.jpg\", \"photo.example.ru/img/3.jpeg\"],
}" http://localhost:8888/v0.1/create_ad
Пример успешного ответа:
{
"status": "success",
"id": 1
}
Пример неудачного ответа:
{
"status": "error",
"id": null
}
/get_ad
)
2. Получить объявление по ID(Пример запроса:
curl -X GET "http://localhost:8888/v0.1/get_ad/1?fields=description&fields=image_urls"
Примеры успешных ответов:
{
"status": "success",
"result": {
"id": 1,
"title": "Гараж",
"description": "Продам гараж!",
"price": 99999.99,
"main_image_url": "garage.ru/img/1.png",
"image_urls": ["supergarage.ru/img/2.jpeg"]
}
}
Или:
{
"status": "success",
"result": {
"id": 1,
"title": "Гараж",
"description": "Продам гараж!",
"price": 99999.99,
"main_image_url": null,
"image_urls": []
}
}
Пример неудачных ответов:
{
"status": "error",
"result": null
}
3.1. Получить список объявлений для пагинации(вторые 10 объявлений с сортировкой по дате по возрастанию, в случае 13 объявлений в БД)
Пример запроса:
curl -X GET "http://localhost:8888/v0.1/list_ads?by=created_at&asc=true&offset=10"
Пример ответа:
{
"status": "success",
"result": [
{
"id": 11,
"title": "Гараж",
"description": "Продам гараж!",
"price": 99999.99,
"main_image_url": null,
"image_urls": []
},
{
"id": 12,
"title": "Тетрадь в клетку",
"description": "",
"price": 79.89,
"main_image_url": null,
"image_urls": []
},
{
"id": 13,
"title": "Книга №42",
"description": "",
"price": 979.29,
"main_image_url": null,
"image_urls": []
}
]
}
3.2. Получить список объявлений для пагинации(первые 10 объявлений с сортировкой по цене по убыванию)
Пример запроса:
curl -X GET "http://localhost:8888/v0.1/list_ads?by=price&asc=false"
Пример ответа:
{
"status": "success",
"result": [
{
"id": 1,
"title": "Гараж",
"description": "Продам гараж!",
"price": 99999.99,
"main_image_url": "garage.ru/img/1.png",
"image_urls": []
},
{
"id": 2,
"title": "Тетрадь в клетку",
"description": "",
"price": 79.89,
"main_image_url": null,
"image_urls": []
},
{
"id": 3,
"title": "Книга №42",
"description": "",
"price": 979.29,
"main_image_url": null,
"image_urls": []
},
{
"id": 4,
"title": "Уловка 22",
"description": "Роман американского писателя Джозефа Хеллера, опубликованный в 1961 году. ",
"price": 629.99,
"main_image_url": null,
"image_urls": []
},
{
"id": 5,
"title": "Обои",
"description": "Рулон обоев",
"price": 2629.99,
"main_image_url": null,
"image_urls": []
},
{
"id": 6,
"title": "Воздух",
"description": "Свежий воздух",
"price": 9999999.99,
"main_image_url": null,
"image_urls": []
},
{
"id": 7,
"title": "Дженга",
"description": "Настольная игра...",
"price": 999,
"main_image_url": null,
"image_urls": []
},
{
"id": 8,
"title": "Сахар",
"description": "На развес, цена за 1 кг",
"price": 57.87,
"main_image_url": null,
"image_urls": []
},
{
"id": 9,
"title": "Соль",
"description": "Цена за килограмм",
"price": 15,
"main_image_url": null,
"image_urls": []
},
{
"id": 10,
"title": "Ноутбук",
"description": "",
"price": 16999.99,
"main_image_url": "top.laptops/ultra/1.jpeg",
"image_urls": []
}
]
}
TODOs
- Добавить
Sentry
- Добавить
Prometheus
,Grafana
- Добавить
Master-Slave репликацию
дляPostgres
- Добавить
HA Proxy
/Consul
/pgpool
/pgbouncer
- Добавить
nginx
(сConsul
) и запустить копии сервиса - Сгенерировать и хостить
Swagger
-документацию - Добавить
DELETE
(удаления записей) иPUT
(изменения записей) методы в сервис - Добавить тестирование через
dockertest
- Добавить singleflight для кэширования и устранения проблем с дублирующимися запросами
- Добавить connection pool
- Добавить обработку через easyjson
Оригинальный текст
Задача
Разработать сервис для подачи объявлений с сохранением в базе данных. Сервис должен предоставлять API, работающее поверх HTTP в формате JSON.
Требования
- Язык программирования — Go;
- Готовую версию выложить на Github;
- Простая инструкция для запуска(в идеале
— с возможностью запустить через
docker-compose up
, но это необязательно); - 3 метода:
- получение списка объявлений,
- получение одного объявления,
- создание объявления;
- Валидация полей:
- не больше 3 ссылок на фото,
- описание не больше 1000 символов,
- название не больше 200 символов;
Если есть сомнения по деталям — решение принять самостоятельно,
но в своём README.md
рекомендуем выписать вопросы и принятые решения по ним.
Ограничения по времени
2-4 часа на выполнение. Если что-то не укладывается в указанное время, то реализовать задачу по степени важности функционала. Мы не требуем выполнить абсолютно всё. Здесь важны умение приоритизировать и чистота кода.
Детали
Метод получения списка объявлений
- Пагинация: на одной странице должно присутствовать 10 объявлений;
- Cортировки: по цене(возрастание/убывание) и по дате создания(возрастание/убывание);
- Поля в ответе: название объявления, ссылка на главное фото (первое в списке), цена.
Метод получения конкретного объявления
- Обязательные поля в ответе: название объявления, цена, ссылка на главное фото;
- Опциональные поля (можно запросить, передав параметр fields): описание, ссылки на все фото.
Метод создания объявления:
- Принимает все вышеперечисленные поля: название, описание, несколько ссылок на фотографии (сами фото загружать никуда не требуется), цена;
- Возвращает ID созданного объявления и код результата (ошибка или успех).