budden / rqr

rqr = (http) requester

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

rqr

rqr = (http) requester

Замечания о выполнении задания

Части в ТЗ, где было непонятно или неоднозначно

Список просьб должен сохраняться на сервере, например в map.

Не сказано, должен ли сохраняться список просьб вместе с результатом, и что делать с некорректными просьбами (содержащими неверную структуру запроса или такие, которые нам не удалось выполнять). При реальной работе мы бы обратились к автору задания, а данное задание - тестовое. Было принято решение действовать простейшим образом - сохранять только успешно выполненные просьбы (например, если произошла ошибка при чтении запроса, мы не считаем это успехом), причём сохранять их вместе с нашим ответом.

Также неясно, что делать при повторном поступлении идентичной просьбы. Мы не пытаемся найти подобную просьбу, а выполняем просьбу заново.

Мьютексы

Задача предполагает, что кандидат покажет знание перечисленных выше пунктов за исключением, может быть, goroutine/chan/sync.Mutex.

Поскольку http порождает горутины для обработки http запросов, мьютекс необходим для выполнения задания.

Имена маршрутов и полей JSON-объектов

Так же мы хотели бы увидеть код приближённый к продакшн версии с понятными наименованиями переменных и http route-ов

Мы назвали просьбу fetchtask. В роутах можно было назвать её fetch-task, но мы выбрали название без чёрточек, чтобы можно было грепом найти все вхождения слова fetchtask, будь то маршрут или имя переменной. По этой же причине не получилось взять fetch_task - линтер ругается на подчёркивания в именах переменных golang. fetchTask мы тоже не стали применять, т.к. смешанный регистр не может применяться в именах файлов и не особо хорош в URL-ах. Поэтому получилось fetchtask, что не слишком хорошо читается.

В записях, подлежащих сериализации в JSON, мы называем поля с использованием только одной заглавной буквы - мы бы назвали их так же, как и маршруты, и по тем же причинам (ведь есть ещё и отображение на поля базы данных, а базы данных обычно нечувствительны к регистру), но неэкспортируемые поля не сериализуются в JSON.

Имена переменных

В примерах из официальной документации можно видеть одно-, двух-, трёхбуквенные идентификаторы, например, w, req, t. Мы следуем этому стилю. Подразумевается, что текст будет читаться в IDE. Когда что-то непонятно, можно подвести курсор мыши и IDE (VS Code в нашем случае) показывает тип данных. Тип данных уже назван подробно и тем самым достигается одновременно лаконичность текста и понятность названий.

Обработка ошибок

Принятая в Go идиома if err != nil слишком многословна. Мы сокращаём её двумя способами:

  • если функция f вызывает функцию g и выходит, то мы присваиваем err, который вернула g, именованному возвращаемому значению err в f. Так мы можем сэкономить одну проверку;
  • в некоторых случаях мы возвращаем булево значение wasError, что означает "возникла ошибка, она обработана и теперь нужно прервать вычисление". В нашем случае есть два способа обработки ошибок - сообщить клиенту или записать в лог. Мы делаем это максимально близко к месту возникновения. Всё, что нужно сделать вызывающей функции - это понять, что запрос неудачен и прекратить обработку. Этот подход не идеален, например, мы передаём запрос и ответ глубоко в обработку предметной области. Но у него есть и плюсы в данном конкретном применении.

Кроме того, интерфейс error слишком беден. Иногда приходится полагаться на анализ строкового сообщения об ошибки, что является ненадёжным. Мы сделали свой интерфейс, который расширяет error и позволяет возвращать код ошибки, см. jsonerror.go.

Документация

Линтер ругается, когда публичная сущность не имеет документации. Но в некоторых случаях там совсем нечего написать. Мы были вынуждены делать пустую документацию, чтобы в IDE не висели предупреждения.

Запуск и тестирование

см. testing.md

Что продемонстрировано

  • ✓ описание структур данных
  • ✓ использование интерфейсов
  • ± обработка ошибок (кроме panic/recover())
  • ✓ работа с json
  • ✓ обработка http запросов
  • ✓ использование http.Client
  • ✓ использование стандартных структур данных map/slice
  • ± goroutine/chan/sync.Mutex (только sync.Mutex)

About

rqr = (http) requester


Languages

Language:Go 100.0%