Skip to main content
Writing a basic HTTP server is easy using the net/http package. This example demonstrates the fundamental concepts of creating HTTP handlers and routing requests.

HTTP Handlers

A fundamental concept in net/http servers is handlers. A handler is an object implementing the http.Handler interface. The most common way to write a handler is by using the http.HandlerFunc adapter on functions with the appropriate signature.
package main

import (
	"fmt"
	"net/http"
)

// Functions serving as handlers take a
// `http.ResponseWriter` and a `http.Request` as
// arguments. The response writer is used to fill in the
// HTTP response. Here our simple response is just
// "hello\n".
func hello(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintf(w, "hello\n")
}

func headers(w http.ResponseWriter, req *http.Request) {
	// This handler does something a little more
	// sophisticated by reading all the HTTP request
	// headers and echoing them into the response body.
	for name, headers := range req.Header {
		for _, h := range headers {
			fmt.Fprintf(w, "%v: %v\n", name, h)
		}
	}
}

func main() {
	// We register our handlers on server routes using the
	// `http.HandleFunc` convenience function. It sets up
	// the *default router* in the `net/http` package and
	// takes a function as an argument.
	http.HandleFunc("/hello", hello)
	http.HandleFunc("/headers", headers)

	// Finally, we call the `ListenAndServe` with the port
	// and a handler. `nil` tells it to use the default
	// router we've just set up.
	http.ListenAndServe(":8090", nil)
}

Handler Function Signature

Handler functions must accept two parameters:
1

ResponseWriter

http.ResponseWriter - Used to construct and send the HTTP response back to the client
2

Request

*http.Request - Contains all information about the incoming HTTP request (headers, body, URL, etc.)

Routing Requests

The http.HandleFunc function registers handlers on specific routes:
http.HandleFunc("/hello", hello)
http.HandleFunc("/headers", headers)
This creates a mapping between URL paths and handler functions.

Starting the Server

The http.ListenAndServe function starts the HTTP server:
http.ListenAndServe(":8090", nil)
Passing nil as the second argument tells the server to use the default router that was configured with http.HandleFunc.

Running the Example

# Run the server in the background.
$ go run http-server.go &

# Access the `/hello` route.
$ curl localhost:8090/hello
hello
The server will continue running until you stop it with Ctrl+C or kill the process.

Next Steps

HTTP Client

Learn how to make HTTP requests

Context

Handle request cancellation with context

TCP Server

Build lower-level TCP servers

Build docs developers (and LLMs) love