---
# System prepended metadata

title: Заметки по ревью кода Сидорова В.

---

# Заметки по ревью кода Сидорова В.

*(тестовое задание в контент WB)*

Ревьюер: [Гульков И.С.](https://t.me/isgulkov)

Версия репы: [`799eacd8676fe4566a82085b5b00ba21f28c8c49`](https://github.com/sidorovvadim33/WeatherServiceApi/tree/799eacd8676fe4566a82085b5b00ba21f28c8c49)

Допы:

- [x] 1\. Асинхронное обновление данных
- [x] 2\. Распараллеливание процесса
- [x] 3\. Docker
- [x] 4\. «Для самых смелых»
- [x] 5\. Swagger, тесты, логи

## Несоответствия требованиям

1. Данные обновляются не раз в минуту, а раз в "минуту + время самого обновления"

## Замечания

*Эти пункты в той или иной мере повлияли на оценку*

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

1. В куче мест, где ошибка — обычное дело (в частности, при походе по HTTP, запросе в БД), она обрабатывается "фатал еррором" (крэшем сервера). Это совершенно недопустимо

### Работа с внешним API

1. [Вот тут](https://github.com/sidorovvadim33/WeatherServiceApi/blob/799eacd8676fe4566a82085b5b00ba21f28c8c49/internal/api/weatherClient/weatherClient.go#L33-L55) мы запускаем множество HTTP-запросов во внешний сервис условно одновременно. Так нельзя, нужен рейт-лимит. При 20 городах всё работает, но если городов в базе хотя бы 1117... результат тебе уже известен 🌝


## Придирки по-мелочи

*Эти пункты __не__ повлияли на оценку*

### API самого сервиса

1. Формат тел ответов везде JSON, что прекрасно, но в некоторых случаях (напр. `POST /api/userfavs/...`) ответ приходит просто в виде текста "`1`". Так не годится: если везде JSON, то везде JSON, пусть даже просто `{ok: true}`
2. Система авторизации, в которой с каждым запросом нужно слать пароль — это а) небезопасно и б) колхозно. Раз уж заморочался, мог бы и bearer-токены прикрутить

### Архитектура

1. Что за термины `service` и `storage`? В частности, нахрена нужен `service`, если весь код всё равно в `storage`? Где ты это взял? *(просто у нас в коде ровно то же самое, и я всё это время был уверен, что это эндемическое заболевание)*

### Поддерживаемость и кодстайл

1. Вот это вот:
   
   ```go
    for _, city := range cities {
		city := city
		go func() {
			// Использование city
		}()
	}
   ```
   
   покрасивше ж вот так:
   
   ```go
    for _, city := range cities {
		go func(city cityClient.CityData) {
			// Использование city
		}(city)
	}
   ```

2. `w.WriteHeader(http.StatusOK)` — это no-op
3. А зачем использовать `net.Listen` вообще? HTTP-сервер из `net/http` сам это умеет...
4. Куча мест ([например](https://github.com/sidorovvadim33/WeatherServiceApi/blob/799eacd8676fe4566a82085b5b00ba21f28c8c49/internal/api/weatherClient/weatherClient.go#L36)), где переменная объявляется в самом начале функции, хотя используется только через 20–30 строк. Это чё, C89?

