HTTP-клиент поиска на Go: обработка ответа и ошибок — задача
Практическая задача на Go по теме «Когда поиск стоит вынести из Article API». Условие содержит контракт функций, предоставленные типы и требования к результату. Используйте выданный шаблон и сохраняйте его публичные объявления. Перед проверкой разберите успешный путь, обработку ошибок и отмену операции, когда она предусмотрена контрактом. Здесь оценивается конкретный компонент сервиса; в полном курсе микросервисов на Go эти компоненты связываются с HTTP, PostgreSQL, gRPC и Kafka.
Когда система статей начинает расти, поиск по ним нередко становится отдельной заботой: он требует собственного индекса, собственной памяти и собственного цикла обновления. Один из распространённых ответов на это — вынести поисковый движок в отдельный процесс, чтобы его ресурсы и выпуск программы можно было настраивать отдельно. Article API при этом по-прежнему умеет искать — просто теперь за ответом ему нужно обратиться куда-то за пределы собственного процесса.
Внутри Article API поиск спрятан за интерфейсом: вызывающий код не знает и не должен знать, где физически находится поисковый движок. До выноса Search в отдельный процесс это мог быть локальный объект; теперь за тем же интерфейсом должен стоять адаптер, который умеет разговаривать с удалённым сервисом по HTTP. Адаптер получает поисковый запрос, доставляет его Search целым и невредимым — со всеми пробелами и специальными символами, — получает список идентификаторов статей с фрагментами текста и возвращает его вызывающему коду.
Граница процессов добавляет зависимость от связи с Search. Сервис может ответить неожиданным образом, а чтение ответа — завершиться с ошибкой; локальная реализация также может возвращать ошибки или реагировать на отмену контекста. Все эти случаи должны оставаться ошибками — адаптер не вправе молча подменить их пустым результатом, который вызывающий код воспримет как законный ответ «ничего не найдено». При этом настоящий пустой результат, когда Search просто не нашёл совпадений, является совершенно нормальным исходом и ошибкой не считается. Кроме того, адаптер уважает контекст, в котором его вызвали: если вызывающий код отменил ожидание или ограничил его по времени, адаптер реагирует на это, а не продолжает работу вхолостую.
Что уже дано
Проверяющая система предоставляет тип Hit с полями ID string, Snippet string (JSON-ключи id, snippet), интерфейс Searcher и RemoteSearcher{addr string}. Перед вашим методом подключены context, encoding/json, fmt, net/http, net/url и стандартные вспомогательные импорты. Адрес addr — абсолютный базовый HTTP-URL без завершающего слеша, пути и query. Используйте http.DefaultClient: он предоставлен системой и позволяет выполнить задачу без внешнего сервиса. Типы уже заданы в полном шаблоне. Сохраните их; main добавлять не нужно.
Что нужно сделать
Реализуйте func (s RemoteSearcher) Search(ctx context.Context, query string) ([]Hit, error). Выполните GET на <addr>/search с единственным query-параметром q, точно сохраняющим поисковую строку после URL-декодирования. Запрос должен использовать переданный контекст, включая отмену и deadline.
При HTTP 200 декодируйте JSON-массив в []Hit, сохраняя порядок и значения; массив [] — успешный пустой результат, допустимы как пустой срез, так и nil при nil ошибке. Любой другой полученный статус должен давать ненулевую ошибку с числовым кодом статуса в её тексте. Ошибки создания запроса, транспорта, чтения и декодирования также возвращайте как ошибки, без паники и подмены успешным поиском. Закройте тело каждого успешно полученного HTTP-ответа, включая неуспешный статус и ошибку декодирования. Точный текст остальных ошибок не задан. Повторы запросов не требуются.
Ввод и вывод
Система вызывает метод с контекстом и строкой query; метод возвращает найденные элементы и ошибку. Вам не нужно читать stdin или печатать в stdout. Однофайловая программа системы читает служебный JSON из stdin и формирует результат проверки.
Формат ввода
Служебный JSON-сценарий для предоставленной программы; его чтение уже реализовано системой. Видимый пример можно запустить без изменения метода или main.
Формат вывода
Публичный адаптер возвращает JSON с фактическими наблюдениями: найденные элементы или наличие ошибки, параметры запроса и закрытие тела ответа. Ожидаемые наблюдения сравнивает сервер.
Запуск на Latorn: редактируйте реализацию в полном шаблоне, сохраняя предоставленные объявления и публичный адаптер RunScenarios. main не требуется. Адаптер принимает массив сценариев и возвращает наблюдения; ожидаемые результаты сравниваются отдельно на сервере. Для собственного запуска аргументы — JSON-массив с одним массивом сценариев: [[...]].
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Go: Принять только полный ответ о последней статье — задача с проверкой
- Go: Декодирование артефакта из JSON — задача с проверкой
- Go: Обязательная и необязательная зависимость при отказе — задача с проверкой
- Go: HTTP-обработчик поиска задания через JobStore — задача с проверкой
- Go: HTTP-обработчик расчёта калорийности состава — задача с проверкой
- Go: Контрактный тест обработчика и клиента питания — задача с проверкой
