Go > Web Development > HTTP Basics > net/http package overview

Simple Web Server using net/http

This snippet demonstrates creating a basic HTTP server in Go using the net/http package. It includes handling a single route and responding with a simple text message. This example introduces the core concepts of handling HTTP requests in Go.

Code Example: Basic HTTP Server

This code creates a simple HTTP server that listens on port 8080. The handler function is registered to handle requests to the root path ('/'). When a request is received, the handler writes 'Hello, World!' along with the requested URL path to the HTTP response. http.HandleFunc associates the '/' route with the 'handler' function. Finally, http.ListenAndServe starts the server, listening for incoming connections on the specified port. Note that if http.ListenAndServe encounters an error, it will log a fatal error and exit the program.

package main

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

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, World! You've requested: %s\n", r.URL.Path)
}

func main() {
	http.HandleFunc("/", handler)

	fmt.Println("Server listening on port 8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

Concepts Behind the Snippet

This snippet illustrates the core concepts of handling HTTP requests in Go:

  • HTTP Handlers: Functions that implement the http.Handler interface. They receive an http.ResponseWriter for writing the response and an http.Request containing information about the request.
  • Routing: Mapping specific URL paths to corresponding handler functions using http.HandleFunc.
  • Server Initialization: Creating an HTTP server instance and binding it to a specific port using http.ListenAndServe.

Real-Life Use Case

This basic structure forms the foundation for more complex web applications. It can be extended to handle different routes, serve static files, process form data, and interact with databases.

Best Practices

  • Error Handling: In a production environment, proper error handling is crucial. Check the return values of functions like http.ListenAndServe and log errors appropriately.
  • Configuration: Avoid hardcoding port numbers and other configuration values. Use environment variables or configuration files to make the application more flexible.
  • Logging: Implement robust logging to track requests, errors, and other important events.

Interview Tip

When discussing this snippet in an interview, be prepared to explain the role of each component (handler, router, server), how HTTP requests are processed, and the importance of error handling and security.

When to use them

Use this pattern when you need to create a simple web server for prototyping, testing, or serving basic content. It's also a good starting point for building more complex web applications.

Alternatives

For more complex web applications, consider using web frameworks like Gin, Echo, or Fiber, which provide additional features such as routing, middleware, and templating.

Pros

  • Simple and easy to understand
  • No external dependencies
  • Good for small projects or learning purposes

Cons

  • Lacks features of web frameworks (e.g., routing, middleware)
  • Can become complex to manage for large applications
  • Requires manual error handling and configuration

FAQ

  • What does the http.ListenAndServe function do?

    The http.ListenAndServe function starts an HTTP server and listens for incoming connections on the specified TCP network address. It takes two arguments: the address to listen on (e.g., ':8080') and a handler to use for incoming requests. If the handler is nil, the DefaultServeMux is used.
  • What is the purpose of the http.ResponseWriter interface?

    The http.ResponseWriter interface is used by an HTTP handler to construct an HTTP response. It allows you to write the response body, set headers, and specify the HTTP status code.
  • How can I handle different HTTP methods (GET, POST, etc.)?

    You can inspect the r.Method field in the http.Request to determine the HTTP method and then execute different logic accordingly. You can also use a router that supports method-specific routes.