The `net/http` package in Go
Documentation: Basic Use of Go’s net/http
Package
The net/http
package in Go is a powerful and versatile library for building HTTP clients and servers. This document provides a basic introduction to its usage, with short explanations and simple code examples.
1. Setting Up an HTTP Server
To start an HTTP server, you can use the http.HandleFunc
function to define routes and their corresponding handler functions.
Example: Basic HTTP Server
package main
import ( "fmt" "net/http")
func helloHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World!")}
func main() { http.HandleFunc("/hello", helloHandler) // Route definition
fmt.Println("Starting server on :8080...") if err := http.ListenAndServe(":8080", nil); err != nil { fmt.Println("Error starting server:", err) }}
Explanation
http.HandleFunc
: Maps the"/hello"
route to thehelloHandler
function.http.ListenAndServe
: Starts the server on port 8080.helloHandler
: Writes “Hello, World!” as the response.
Run the program and access http://localhost:8080/hello
to see the message.
patterns for matching routes
A pattern has three optional parts: [METHOD ][HOST]/[PATH]
Key rules:
- METHOD must be followed by space/tab if present
- No method = matches all methods
- GET matches both GET and HEAD
- No host = matches all hosts
- Paths can contain wildcards in two forms:
{NAME}
: Matches one path segment{NAME...}
: Matches all remaining segments
Examples:
"/index.html" // Matches exact path, any host/method"GET /static/" // Matches GET requests starting with /static/"example.com/" // Matches any request to example.com"example.com/{$}" // Matches exactly "/" on example.com
Path segments are unescaped before matching, so “/a%2Fb” is treated as “/a/b”.
2. Making HTTP Requests
The http
package includes tools for creating HTTP clients to send requests to other servers.
Example: Making a GET Request
package main
import ( "fmt" "net/http" "io/ioutil")
func main() { response, err := http.Get("https://jsonplaceholder.typicode.com/posts/1") if err != nil { fmt.Println("Error making GET request:", err) return } defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body) if err != nil { fmt.Println("Error reading response body:", err) return }
fmt.Println("Response:", string(body))}
Explanation
http.Get
: Sends a GET request to the specified URL.response.Body
: Contains the response body, which is read usingioutil.ReadAll
.defer response.Body.Close()
: Ensures the response body is closed after use.
3. Handling Query Parameters
Query parameters can be extracted using the r.URL.Query
method.
Example: Extract Query Parameters
package main
import ( "fmt" "net/http")
func queryHandler(w http.ResponseWriter, r *http.Request) { params := r.URL.Query() name := params.Get("name") if name == "" { name = "Guest" } fmt.Fprintf(w, "Hello, %s!", name)}
func main() { http.HandleFunc("/greet", queryHandler)
fmt.Println("Starting server on :8080...") http.ListenAndServe(":8080", nil)}
Explanation
r.URL.Query()
: Parses query parameters into a map-like structure.params.Get("name")
: Retrieves the value of thename
parameter.
Access http://localhost:8080/greet?name=Areen
to see the greeting with your name.
4. Using Custom Handlers
For more control, implement the http.Handler
interface with a custom struct.
Example: Custom Handler
package main
import ( "fmt" "net/http")
type myHandler struct{}
func (h *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Custom handler response!")}
func main() { handler := &myHandler{} fmt.Println("Starting server on :8080...") http.ListenAndServe(":8080", handler)}
Explanation
ServeHTTP
: Method required to implement thehttp.Handler
interface.- Custom handler provides more flexibility in handling requests.
5. Middleware Example
Middleware allows pre- or post-processing of HTTP requests and responses.
Example: Logging Middleware
package main
import ( "fmt" "net/http")
func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Printf("%s %s\n", r.Method, r.URL.Path) next.ServeHTTP(w, r) })}
func mainHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Welcome!")}
func main() { mainHandler := http.HandlerFunc(mainHandler) http.Handle("/", loggingMiddleware(mainHandler))
fmt.Println("Starting server on :8080...") http.ListenAndServe(":8080", nil)}
Explanation
- Middleware wraps handlers to add functionality (e.g., logging).
loggingMiddleware
prints the request method and path before passing it to the next handler.
This document covers basic functionality to help you get started with Go’s net/http
package. Explore further by combining these examples and creating more advanced HTTP applications!
Here’s a list of the most commonly used functions in Go’s net/http
package, categorized by functionality:
Server-Side Functions
-
http.HandleFunc
Maps a route to a handler function.http.HandleFunc("/path", handlerFunction) -
http.ListenAndServe
Starts an HTTP server on a specified address and port.http.ListenAndServe(":8080", nil) -
http.Serve
Serves HTTP requests on a customnet.Listener
.http.Serve(listener, handler) -
http.ServeMux
A request multiplexer for handling routes.mux := http.NewServeMux()mux.Handle("/path", handler) -
http.FileServer
Serves static files from a directory.http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
Client-Side Functions
-
http.Get
Sends an HTTP GET request and returns the response.resp, err := http.Get("http://example.com") -
http.Post
Sends an HTTP POST request with a body.resp, err := http.Post("http://example.com", "application/json", body) -
http.PostForm
Sends an HTTP POST request with form-encoded data.resp, err := http.PostForm("http://example.com", url.Values{"key": {"value"}}) -
http.NewRequest
Creates a new HTTP request with custom headers or methods.req, err := http.NewRequest("GET", "http://example.com", nil) -
http.DefaultClient.Do
Executes a customhttp.Request
.resp, err := http.DefaultClient.Do(req)
Request and Response Handling
-
http.Redirect
Redirects the client to a new URL.http.Redirect(w, r, "http://new-url.com", http.StatusFound) -
http.Error
Sends an HTTP error response with a status code.http.Error(w, "Something went wrong", http.StatusInternalServerError) -
http.NotFound
Sends a 404 Not Found response.http.NotFound(w, r) -
http.ServeContent
Serves content with caching headers.http.ServeContent(w, r, "filename", modTime, content) -
http.ServeFile
Serves a file directly to the client.http.ServeFile(w, r, "./path/to/file")
Utilities
-
http.NewServeMux
Creates a new multiplexer for routing.mux := http.NewServeMux() -
http.StripPrefix
Strips a prefix from a URL path before routing.http.StripPrefix("/static/", handler) -
http.TimeoutHandler
Wraps a handler with a timeout.http.TimeoutHandler(handler, 2*time.Second, "Request timed out") -
http.ParseForm
Parses form data from a request.err := r.ParseForm() -
http.Header
Allows access to HTTP headers.r.Header.Get("Content-Type")
These functions cover the most common use cases for creating HTTP servers, handling client requests, and making HTTP requests in Go.