logo

Golang - HTTP

Last Updated: 2023-09-03

HTTP Server

There are 2 parts of an HTTP server in go: handlers and server

  • http.HandleFunc: the logic of the handlers
  • http.ListenAndServe: start the server and listen to new HTTP requests.

Basic example

package main

import (
	"fmt"
	"io"
	"net/http"
)

func handleRoot(w http.ResponseWriter, r *http.Request) {
	fmt.Println("Handling request: /")
	io.WriteString(w, "Home page\n")
}
func handleFoo(w http.ResponseWriter, r *http.Request) {
	fmt.Println("Handling request: /foo")
	io.WriteString(w, "Foo page\n")
}

func main() {
	http.HandleFunc("/", handleRoot)
	http.HandleFunc("/foo", handleFoo)

	http.ListenAndServe(":8888", nil)
}

The server will run and block; open another shell as the client and try:

$ curl localhost:8888
Home page

$ curl localhost:8888/foo
Foo page

Note:

  • inside the HandleFunc, fmt.Println() prints to the server, while io.WriteString writes to the response so will show in the client shell.

  • http.HandleFunc() uses DefaultServeMux under the hood; you can create your own ServeMux; a ServerMux is basically a set of muxEntry (pairs of string patterns like /foo and Handler). The example above is equivalent to

    mux := http.NewServeMux()
    mux.HandleFunc("/", handleRoot)
    mux.HandleFunc("/foo", handleFoo)
    
    http.ListenAndServe(":8888", mux)
    
  • http.ListenAndServe() creates a http.Server implicitly (only sets Addr and Handler); alternatively you can create your own http.Server; http.ListenAndServe() is equivalent to:

    server := &http.Server{
      Addr:    ":8888",
      Handler: nil,
      // ...
    }
    server.ListenAndServe()