Тестовое задание
Класс реализующий запрос на стороннее API, возвращающее результат в формате
{
total: 110,
userCount: 20,
page: 1,
users: [
{ name: "Joe Doe", rank: 15 },
{ name: "Peter Parker", rank: 39 },
...
]
}
#Получение данных с API Самый очевидный вариант решения проблемы посылать последовательно запросы до тех пор, пока мы не получим всех данных. Проблема в том, что такой вариант займет длительное время, в случае если количество данных велико.
Самый быстрый варинат получения всего перечня пользователей - послать все запросы параллельно, таким образом мы сразу получаем все необходимые данные. Найти количество необходимых запросов мы можем, так как знаем общее количество документов и количество документов на странице.
Делать запрос на данные я буду следующим образом:
- Запрашиваю 1 страницу. Получаю данные по пользователям, получаю информацию о общем количестве записей и о количестве записей в одной странице.
- Рассчитываю сколько запросов дополнительно мне нужно сделать
- Формирую запросы добавляю их в массив запросов. Жду их завершения.
- Формирую и возвращаю результат.
#Структура классов
##Действия совершаемые в контексте задачи
- Совершать сетевые запросы
- Парсить данные ответов
- Осуществлять выборку ответов по критерию
##Возможные изменения
- Может поменяться структура ответа с API сервера.
- Критерий выборки ответов
- Механизм совершения запросов
Таким образом, у меня будет 3 интерфейса - для работы с сетью, для фильтрации данных, для парсинга и валидации. Классы реализующие данные интерфейсы будут находиться в отношении композиции с классом-клиентом. В будущем это позволит либо заменять какие-то блоки, в случае изменений не трогая сам класс-клиент а также упростит возможность тестирования путем передачи в класс-клиент моков.
Также существует вероятность появления на API сервере ограничения на количество запросов в единицу времени. В данный ситуации придется ждать какое-то интервал вермени между запросами, а сами запросы группировать в количестве, допускаемом сервером. Сделать это можно будет путем добавления в очередь групп запросов с ожиданием их резолва. Возможно также использовать setTimeout для длительного ожидание(если это будет нужно). Резолвить асинхронно такие группы запросов я бы стал при поиощи цикла for ... in - он умеет корректно отрабатывать резолв промиса.
Если, к примеру, запросов будет много и станет актуальным вопрос отмены очереди запросов - тогда я бы реализовал метод с ипользованием генераторов. В next генератора можно будет передавать флаг продолжения цикла, а возвращать каждый цикл он может отфильтрованные данные.