Go HTTP Server

Go includes a production-ready HTTP server in its standard library — no frameworks required. The net/http package handles routing, request parsing, response writing, and concurrent connections out of the box. A basic Go HTTP server handles thousands of requests per second with just a few lines of code.

Simplest HTTP Server

package main

import (
    "fmt"
    "net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello, World!")
}

func main() {
    http.HandleFunc("/", helloHandler)
    fmt.Println("Server running at http://localhost:8080")
    http.ListenAndServe(":8080", nil)
}

Open a browser and visit http://localhost:8080 to see: Hello, World!

HTTP Server Components

http.HandleFunc(pattern, handlerFunc)
       │               │
       │               └── func(w http.ResponseWriter, r *http.Request)
       └──────────────────── URL path to match, e.g. "/", "/about"

http.ListenAndServe(address, mux)
       │                │       │
       │                │       └── nil uses the default ServeMux
       │                └────────── ":8080" means all interfaces, port 8080
       └─────────────────────────── starts the server, blocks forever

Handler Function Parameters

ParameterTypePurpose
whttp.ResponseWriterWrite the response (headers, body) back to the client
r*http.RequestContains the incoming request data (URL, method, headers, body)

Multiple Routes

package main

import (
    "fmt"
    "net/http"
)

func homeHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Welcome to the Home Page!")
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "About eStudy247 - Free Learning Platform")
}

func contactHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Contact us at hello@estudy247.com")
}

func main() {
    http.HandleFunc("/", homeHandler)
    http.HandleFunc("/about", aboutHandler)
    http.HandleFunc("/contact", contactHandler)

    fmt.Println("Server running at http://localhost:8080")
    http.ListenAndServe(":8080", nil)
}

Reading Query Parameters

package main

import (
    "fmt"
    "net/http"
)

func greetHandler(w http.ResponseWriter, r *http.Request) {
    name := r.URL.Query().Get("name")
    if name == "" {
        name = "Stranger"
    }
    fmt.Fprintf(w, "Hello, %s!", name)
}

func main() {
    http.HandleFunc("/greet", greetHandler)
    http.ListenAndServe(":8080", nil)
}

Visit: http://localhost:8080/greet?name=Alice
Output: Hello, Alice!

Setting HTTP Status Codes and Headers

package main

import (
    "encoding/json"
    "net/http"
)

type Response struct {
    Message string `json:"message"`
    Status  int    `json:"status"`
}

func apiHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK) // 200

    resp := Response{Message: "Success", Status: 200}
    json.NewEncoder(w).Encode(resp)
}

func notFoundHandler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusNotFound) // 404
    w.Write([]byte("Page not found"))
}

func main() {
    http.HandleFunc("/api", apiHandler)
    http.HandleFunc("/missing", notFoundHandler)
    http.ListenAndServe(":8080", nil)
}

Checking Request Method

package main

import (
    "fmt"
    "net/http"
)

func formHandler(w http.ResponseWriter, r *http.Request) {
    switch r.Method {
    case http.MethodGet:
        fmt.Fprintln(w, "Send a POST request with data")
    case http.MethodPost:
        r.ParseForm()
        username := r.FormValue("username")
        fmt.Fprintf(w, "Received username: %s", username)
    default:
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
    }
}

func main() {
    http.HandleFunc("/form", formHandler)
    http.ListenAndServe(":8080", nil)
}

HTTP Request Lifecycle

Browser/Client
      │
      │  HTTP Request (GET /about)
      ▼
Go HTTP Server (port 8080)
      │
      │  router matches "/about"
      ▼
aboutHandler(w, r) runs
      │
      │  writes response to w
      ▼
Browser/Client receives response

Key Points

  • Go's standard library includes a full HTTP server — no framework needed
  • http.HandleFunc registers a URL pattern and its handler function
  • http.ListenAndServe starts the server and blocks until the program exits
  • Use r.URL.Query().Get("key") to read URL query parameters
  • Set Content-Type headers before writing the body for correct client rendering
  • Each incoming request is handled in its own goroutine automatically by Go's HTTP server

Leave a Comment