liveBook · Manning

Http.Server

As explained in Go by Example

http.Server is Go's HTTP server type that accepts network connections and dispatches requests to a configured handler.

http.Server is the configurable form of a Go HTTP server. It accepts connections and sends each request to its Handler. For a quick start, http.ListenAndServe creates and starts a Server around the handler supplied to it; use an explicit Server when server settings need control. section 8.3.2 section 8.6

Route requests through a handler

A function such as Health can serve requests after conversion with http.HandlerFunc(Health). HandlerFunc adapts a function with ResponseWriter and *Request parameters to the http.Handler interface. Its ServeHTTP method calls the original function, so the running Server invokes Health for every incoming request. section 8.3.2

type HandlerFunc func(ResponseWriter, *Request)  #1

func (f HandlerFunc) ServeHTTP(  #2
    w ResponseWriter, r *Request,   #2
) {  
    f(w, r)  #3
}

Inspect the adapter: HandlerFunc is a function type whose ServeHTTP method forwards the response writer and request to that function. section 8.3.2

Construct http.Server directly when connection behavior matters. Set Handler to the router, Addr to the listening address, and timeout fields suited to the service. This avoids the fixed defaults of the convenience function and makes operational choices visible in the program configuration. section 8.6

Two timeout settings protect resources from slow or unresponsive clients:

  • ReadTimeout limits the interval from accepting a connection until receiving its request, preventing slow requests from occupying server time indefinitely. section 8.6
  • IdleTimeout limits how long an open connection may wait for another request; when the interval expires, the server closes it. section 8.6
  • Choose values for the workload: large uploads may need a longer read timeout than short API calls, while idle time should preserve useful connections without retaining them unnecessarily. section 8.6

Configure a resilient server

Keep the address and timeout durations in configuration, then construct a Server with the application mux as Handler. This permits command-line or deployment-specific tuning while retaining a standard-library server implementation. http.TimeoutHandler can separately protect against handlers that run too long. section 8.6

Listing 8.14 Setting server timeouts (link/cmd/linkd/linkd.go)
package main

import (
    "time"
    . . .
)

type config struct {
    http struct {
        addr     string
        timeouts struct{ read, idle time.Duration }  #1
    }
    lg *slog.Logger
}

func main() {
    var cfg config
    . . .
    flag.DurationVar(
        &cfg.http.timeouts.read, "http.timeouts.read",
        ٢٠*time.Second, "read timeout",
    )
    flag.DurationVar(
        &cfg.http.timeouts.idle, "http.timeouts.idle",
        ٤٠*time.Second, "idle timeout",
    )
    flag.Parse()
    . . .
}

func run(_ context.Context, cfg config) error {
    shortener := new(link.Shortener)
    . . .  #2
    srv := &http.Server{
        Handler:     mux,  #3
        Addr:        cfg.http.addr,  #4
        ReadTimeout: cfg.http.timeouts.read,  #5
        IdleTimeout: cfg.http.timeouts.idle,  #6
    }
    if err := srv.ListenAndServe(); !errors.Is(  #7
        err, http.ErrServerClosed,
    ) {
        return fmt.Errorf("server closed unexpectedly: %w", err)
    }
    return nil
}

This complete setup places address, read timeout, idle timeout, and the request multiplexer on an explicit http.Server. section 8.6

Server also supports realistic tests without replacing HTTP types with mocks. httptest.NewServer runs a Server for testing, while Server can listen on any address and port. Because Handler is an interface field, tests can substitute handlers to isolate routes while exercising real request and response behavior. section 8.8.2

How Go by Example covers it

How deep it goes
Explains handler dispatch, timeout rationale and tuning, and test-server substitution without detailing the server implementation.
Examples
Uses a Health handler, a configured router server, command-line timeout durations, and httptest.NewServer.
What you can do after
Operate/configure it with handlers, addresses, and timeouts, then test routes using isolated servers.
How it connects
Connects Server with http.Handler, HandlerFunc, ReadTimeout, IdleTimeout, http.TimeoutHandler, and httptest.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go by Example. The section links point to the parts of the book it draws on.