HTTP-сервер, JSON API и итоговый проект

HTTP-сервер на net/http: регистрация обработчиков и формирование ответа

Содержание курса

r.Method, r.URL.Path и порядок Header → WriteHeader → Write при формировании ответа

Внутри обработчика r *http.Request содержит всё о входящем запросе. Два самых частых поля:

  • r.Method — строка с HTTP-методом: "GET", "POST", "DELETE" и т.д.
  • r.URL.Path — строка с путём запроса, например "/hello".

Пример использования:

func helloHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodGet {
        w.Header().Set("Content-Type", "text/plain")
        w.WriteHeader(http.StatusMethodNotAllowed)
        fmt.Fprintln(w, "only GET allowed")
        return
    }
    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "Hello from %s\n", r.URL.Path)
}

Порядок вызовов строго обязателен: сначала w.Header().Set(...), затем w.WriteHeader(code), затем запись тела через w.Write(...) или fmt.Fprintf(w, ...).

Почему порядок нельзя нарушать? HTTP-ответ устроен так: сначала идёт статусная строка и заголовки, потом тело. Как только вы начинаете писать тело, заголовки уже уходят клиенту — изменить их невозможно. net/http реализует это жёстко: первый вызов Write или Fprintf автоматически отправляет статус 200 и все текущие заголовки, если WriteHeader ещё не был вызван.

Что будет, если нарушить порядок:

// Неправильно!
func badHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "oops")         // ← здесь неявно уходит статус 200
    w.WriteHeader(http.StatusTeapot) // ← этот вызов игнорируется, уже поздно
}

Клиент получит статус 200, а в логах Go напишет что-то вроде:

http: superfluous response.WriteHeader call from ...

Это предупреждение в stderr, но ответ уже отправлен с неверным статусом.

Одно исключение: если вы отвечаете с кодом 200 и не устанавливаете специальных заголовков, WriteHeader(200) можно не вызывать — первый Write сделает это сам. Но как только нужен другой статус или любой заголовок — следуйте порядку явно.