Creating a Simple Go Web Application with the net/http Package

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setting Up Go
  4. Creating a Simple Web Application
  5. Handling HTTP Requests
  6. Adding Routes and Handlers
  7. Testing the Web Application
  8. Conclusion

Introduction

In this tutorial, we will learn how to create a simple web application using Go and the net/http package. By the end of this tutorial, you will be able to build a basic web server with different routes and handlers to handle HTTP requests. This tutorial assumes basic knowledge of Go programming language.

Prerequisites

Before starting this tutorial, make sure you have the following prerequisites:

  • Basic understanding of Go programming language
  • Go installed on your machine

Setting Up Go

First, we need to ensure that Go is properly installed on your machine. Follow these steps to set up Go:

  1. Download the Go distribution from the official website: https://golang.org/dl/.
  2. Install Go by running the downloaded installer and following the instructions for your operating system.

  3. Verify the installation by opening a command prompt or terminal and typing go version. You should see the version of Go installed on your machine.

    With Go successfully installed, we can now proceed to create our web application.

Creating a Simple Web Application

  1. Create a new directory for your web application. Open a command prompt or terminal, navigate to the desired location, and run the following command:

    ```bash
    mkdir mywebapp
    ```
    
  2. Change into the newly created directory:

    ```bash
    cd mywebapp
    ```
    
  3. Initialize a new Go module by running the following command:

    ```bash
    go mod init mywebapp
    ```
    
    This command creates a new `go.mod` file that will manage the dependencies of our project.
    
  4. Create a new file named main.go using your favorite text editor. This file will contain the code for our web application.

    ```bash
    touch main.go
    ```
    
  5. Open main.go in your text editor and add the following boilerplate code:

    ```go
    package main
    
    import (
    	"fmt"
    	"log"
    	"net/http"
    )
    
    func main() {
    	http.HandleFunc("/", homeHandler)
    
    	log.Println("Starting server on http://localhost:8080")
    	log.Fatal(http.ListenAndServe(":8080", nil))
    }
    
    func homeHandler(w http.ResponseWriter, r *http.Request) {
    	fmt.Fprintln(w, "Welcome to my web application!")
    }
    ```
    
    Let's go through the code to understand what it does:
    
    - We import the necessary packages: `fmt`, `log`, and `net/http`.
    - In the `main` function, we register a handler function `homeHandler` for the root URL ("/"). This handler function will be called whenever a request is made to the root URL.
    - We use the `log` package to print a message indicating that the server is starting on `http://localhost:8080`.
    - Finally, we start the server by calling `http.ListenAndServe(":8080", nil)`. This starts an HTTP server that listens on port 8080.
    

Handling HTTP Requests

Now that we have a basic web application, let’s understand how to handle different types of HTTP requests.

By default, the http package registers the DefaultServeMux as the default HTTP request multiplexer. This means that when we call http.HandleFunc(...), it registers the handler function with the DefaultServeMux. The DefaultServeMux is an HTTP request multiplexer that matches the URL path of each incoming request against a list of registered patterns and calls the corresponding handler function.

In our code, we registered the homeHandler function as the handler for the root URL (“/”). This means that whenever a request is made to the root URL, the homeHandler function is called.

We can register different handlers for different URLs to handle specific requests. Let’s see how to do that.

Adding Routes and Handlers

  1. Open main.go in your text editor and add the following code right before the main function:

    ```go
    func aboutHandler(w http.ResponseWriter, r *http.Request) {
    	fmt.Fprintln(w, "About page")
    }
    ```
    
    This code defines a new handler function `aboutHandler` that simply writes "About page" to the HTTP response.
    
  2. To register the aboutHandler for the “/about” URL, add the following code inside the main function, before the call to http.ListenAndServe(...):

    ```go
    http.HandleFunc("/about", aboutHandler)
    ```
    
    Now, requests made to "/about" will be handled by the `aboutHandler` function.
    
  3. Save the changes and start the server by running the following command in your terminal:

    ```bash
    go run main.go
    ```
    
    The server should start, and you can access the web application by visiting [http://localhost:8080](http://localhost:8080) in your browser.
    
  4. Try accessing http://localhost:8080/about to see the “About page” in action.

    You can register as many routes and handlers as needed based on your application requirements. Now that we know how to handle different routes and requests, let’s test our web application.

Testing the Web Application

To test our web application, we can use the net/http/httptest package, which provides a set of utilities for testing HTTP servers.

  1. Create a new file named main_test.go in the same directory as main.go.

    ```bash
    touch main_test.go
    ```
    
  2. Open main_test.go in your text editor and add the following code:

    ```go
    package main
    
    import (
    	"net/http"
    	"net/http/httptest"
    	"testing"
    )
    
    func TestHomeHandler(t *testing.T) {
    	req, err := http.NewRequest("GET", "/", nil)
    	if err != nil {
    		t.Fatal(err)
    	}
    
    	rr := httptest.NewRecorder()
    	handler := http.HandlerFunc(homeHandler)
    
    	handler.ServeHTTP(rr, req)
    
    	if rr.Code != http.StatusOK {
    		t.Errorf("expected status code %v, got %v", http.StatusOK, rr.Code)
    	}
    
    	expected := "Welcome to my web application!"
    	if rr.Body.String() != expected {
    		t.Errorf("expected response body %q, got %q", expected, rr.Body.String())
    	}
    }
    ```
    
    This code defines a test function `TestHomeHandler` that sets up a new HTTP request using `http.NewRequest(...)`, creates a response recorder `rr` using `httptest.NewRecorder()`, and calls the `homeHandler` function using `handler.ServeHTTP(rr, req)`.
    
    It then checks the response status code using `rr.Code` and the response body using `rr.Body.String()`.
    
  3. To run the tests, open a terminal, navigate to the directory containing main.go and main_test.go, and execute the following command:

    ```bash
    go test
    ```
    
    You should see the test output indicating whether the test passed or failed.
    
    ```
    PASS
    ```
    
    This means our test passed successfully.
    

    You can write additional tests to cover other handler functions or specific routes. Testing our web application helps ensure that it works as expected and captures any issues early on.

Conclusion

In this tutorial, we learned how to create a simple web application using Go and the net/http package. We covered the basics of handling HTTP requests, registering routes and handlers, and testing our web application. You should now have a good understanding of how to build a basic web server in Go.

Remember, this is just the starting point, and there’s a lot more you can do with Go and web development. Explore the Go documentation and experiment with building more complex web applications to further enhance your skills in Go programming.

Happy coding!