Comments 5
Молодцы, что написали статью! Не уверен, что я бы стал на вашем месте рекомендовать эту книгу. В приведенных отрывках кода довольно много недочетов, которые лично мне бросились в глаза:
err := req.ParseForm()
if err != nil {
rw.WriteHeader(http.StatusInternalServerError)
rw.Write([]byte(err.Error()))
return
}
Здесь сразу несколько проблем:
Если не удалось распарсить форму, то это не Internal Server Error. Почти во всех (или вообще во всех) случаях ошибки, которые может вернуть ParseForm, возникают из-за недопустимого формата запроса, например как вот тут
Есть отдельный метод http.Error, который намного компактнее позволяет записывать возврат ошибки в HTTP обработчике: https://pkg.go.dev/net/http#Error
result, err := logic(ctx, data)
if err != nil {
rw.WriteHeader(http.StatusInternalServerError)
rw.Write([]byte(err.Error()))
return
}
Точно также, здесь если логика вернула ошибку, она не обязательно (но может быть) связана с тем, что что-то пошло не так на стороне сервера. Код логики должен либо дополнительно возвращать нужный HTTP код ошибки, либо возвращать такой тип ошибки, в котором также содержится HTTP статус-код.
req, err := http.NewRequest(http.MethodGet,
"http://example.com?data="+data, nil)
Данные в запросе должны экранироваться, лучше всего с помощью структуры url.Values и метода Encode()
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("Unexpected status code %d",
resp.StatusCode)
}
Очень распространённая ошибка: тело запроса не вычитывается до конца, если произошла ошибка (не в смысле, что метод .Do() вернул ошибку, а что сервер ответил, но с HTTP кодом отличным от 200. В этом случае (если тело запроса не прочитано) соединение с сервером будет закрыто и keep-alive для соединения не будет работать. Это становится важно, когда запросов к одному и тому же серверу выполняется много: могут даже закончиться исходящие порты на сервере, который отправляет запросы.
err := callServer(ctx, "fast", fastURL+"?error="+errVal)
Аналогично, нет экранирование значения
Go: идиомы и паттерны проектирования
Ожидание: вот книга где наконец-то расскажут как строить архитектуру приложений в Go! Наконец-то смогу узнать как наилучшим образом применять SOLID и GoF в Go!
Реальность: ещё одна книга по основам Go. Зачем, если есть книга Алана Донавана и Брайна Кернигана?
Надеюсь в книге будет описано зачем и почему был выбран такой странный синтаксис обработки исключений?
data, err := ioutil.ReadAll(resp.Body)
if err != nil {...
Книга «Go: идиомы и паттерны проектирования»