К сожалению, я не думаю, что найдется ответ, которым вы довольны.В конце дня должно быть верно следующее:
Каждый обработчик должен использовать http.Responsewriter
и *http.Request
для обслуживания запроса.
Следует помнить, что корочеи проще не всегда идут рука об руку.Передача автора и ответ на функции, которые в них нуждаются, хотя и немного многословны, чрезвычайно просты.
Что может сделать вас счастливее, так это вместо этого подтолкнуть большую часть логики фактически к некоторым дополнительным методам, которые имеют дело с семантикой операций, а не с уровнем сетевых запросов.Используя GET-запрос для загрузки записи в качестве примера, вы могли бы вместо этого структурировать ее следующим образом:
func main() {
http.DefaultServeMux.HandleFunc("/", getHandler)
if err := http.ListenAndServe(":8080", nil); err != nil {
panic(err)
}
}
func getHandler(w http.ResponseWriter, r *http.Request) {
// Do stuff with the request, like deserialize
// Extract the ID
// Call getLogic
// return an appropriate error or serialize the response back out
}
func getLogic(recordID int) (Record, error) {
// Do actual interesting logic here.
}
Разделение на части так, как это не без потенциальных затрат в простоте.Хотя он позволяет вам тестировать куски вашей логики без необходимости иметь дело с http.ResponseWriter
или http.Request
, теперь вы должны принять решение, где разрезать этот шов.Постоянно делать это может быть неловко.
Вы также можете попытаться использовать другие подходы, такие как создание структуры для каждого запроса, наложение автора и запроса на него, а затем вызывать соответствующий метод, но я бы не рекомендовалэто:
func getHandler(w http.ResponseWriter, r *http.Request) {
SingleRequest{w, r}.Get()
}
type SingleRequest struct {
writer http.ResponseWriter
request *http.Request
}
func (s SingleRequest) Get() {
// Do logic here, but the method still has to access s.writer and s.request
}
Ни один из этих подходов не предлагает много с точки зрения простоты краткости.Какая незначительная краткость, которую они действительно дают, на мой взгляд, за счет простоты.Первый подход, однако, может быть разумным в зависимости от сложности данного обработчика.В конце концов, это расширение шаблона создания меньших функций для разбиения большей функции.
В настоящее время я не знаю ни одного подхода, который повсеместно увеличивает простоту при уменьшении размера кода.Вместо этого мы должны сосредоточиться на том, почему вы чувствуете, что это проблема, которую нужно решить в первую очередь.Вы знакомы с пакетом httptest в стандартной библиотеке lib?Если вас интересует тестирование, это поможет вам протестировать эти обработчики.