Building a Simple Web Server in Go

Gigi Kenneth
4 min read3 days ago

--

For context: on a warm Sunday afternoon, I asked NicoNex to teach me something cool in his favourite programming language, Go, and he taught me this, so here you go 😂:

In this tutorial, we will build a simple web server using Go that handles HTTP requests and returns data in JSON format. We will create endpoints to greet users and to return information about a penguin.

Table of Contents

¡ Prerequisites
¡ Step 1: Setting Up the Project
¡ Step 2: Writing the Code
∘ What’s happening?
∘ What’s happening?
∘ What’s happening here?
¡ Step 3: Running the Server
¡ Full Code
¡ Tip: Formatting Your Code
¡ Conclusion

Prerequisites

Step 1: Setting Up the Project

First, create a new directory for your project and navigate into it using Terminal:

mkdir penguin-server
cd penguin-server

Create a new file named main.go and open it in your favorite code editor (I use VS Code).

Step 2: Writing the Code

Let’s start by writing the necessary imports and defining our penguin struct. You can name it whatever you want. Penguin was the first thing that popped in my head.

package main

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

type penguin struct {
Name string
Age int
Colour string
}

What’s happening?

package main : This line defines the package name. In Go, every file begins with a package declaration. Here, we’re using main, which is a special name that tells Go to build an executable program.

These lines import the necessary packages:

  • encoding/json: Used for JSON encoding and decoding.
  • io: Provides basic input and output functions.
  • net/http: Used for HTTP client and server implementations.

This block defines a struct type named penguin.

  • A struct in Go is a collection of fields.
  • Here, penguin has three fields: Name, Age, and Colour.

Next, we will set up our main function to handle HTTP requests.

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

What’s happening?

  • func main() { ... }: This defines the main function, which is the entry point of the Go program.
  • http.HandleFunc("/greet", handleGreet): This line tells the http package to handle requests to the /greet path using the handleGreet function.
  • http.HandleFunc("/penguin", handlePenguin): This line tells the http package to handle requests to the /penguin path using the handlePenguin function.
  • http.ListenAndServe(":8080", nil): This starts an HTTP server on port 8080. nil means we're using the default ServeMux.

Now, let’s define the handler functions. The first function will greet the user, and the second function will return information about a penguin in JSON format. PS: Go’s documentation is your friend.

func handleGreet(response http.ResponseWriter, request *http.Request) {
io.WriteString(response, "Hello, friend!\n")
}

func handlePenguin(response http.ResponseWriter, request *http.Request) {
p := penguin{
Name: "Sam",
Age: 3,
Colour: "Blue",
}
b, _ := json.Marshal(p)
response.Write(b)
}

What’s happening here?

  • func handleGreet(response http.ResponseWriter, request *http.Request) { ... }: This defines the handleGreet function, which takes an http.ResponseWriter and an *http.Request as arguments.
  • io.WriteString(response, "Hello, friend!\n"): This writes the string "Hello, friend!" to the HTTP response.
  • func handlePenguin(response http.ResponseWriter, request *http.Request) { ... }: This defines the handlePenguin function, which also takes an http.ResponseWriter and an *http.Request as arguments.
  • p := penguin{ ... }: This creates an instance of the penguin struct with the name "Sam", age 3, and color "Blue".
  • b, _ := json.Marshal(p): This converts the penguin struct p to JSON format. json.Marshal returns the JSON encoding of p as b.
  • response.Write(b): This writes the JSON-encoded penguin to the HTTP response.

Step 3: Running the Server

Save your file and run the server using the following command:

go run main.go

Your server should now be running on http://localhost:8080. You can test the endpoints using a web browser or a tool like curl.

  • To test the greet endpoint, navigate to http://localhost:8080/greet. You should see the message "Hello, friend!".
  • To test the penguin endpoint, navigate to http://localhost:8080/penguin. You should see the penguin information in JSON format:
{
"Name": "Sam",
"Age": 3,
"Colour": "Blue"
}

Full Code

package main

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

type penguin struct {
Name string
Age int
Colour string
}

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

func handleGreet(response http.ResponseWriter, request *http.Request) {
io.WriteString(response, "Hello, friend!\n")
}

func handlePenguin(response http.ResponseWriter, request *http.Request) {
p := penguin{
Name: "Sam",
Age: 3,
Colour: "Blue",
}
b, _ := json.Marshal(p)
response.Write(b)
}

Tip: Formatting Your Code

Before running your Go code, it’s a good practice to format it. You can use the go fmt to automatically do that so your code looks cleaner.

go fmt swanlake.go

Conclusion

You did it! You have successfully created a simple web server in Go that handles HTTP requests and returns JSON data. This tutorial covered the basics of setting up a server, defining endpoints, and returning data in JSON format.

I feel like something is missing in this post, so fingers crossed I can figure that out.

You can expand on this project by adding more endpoints and functionalities if you want.

💁🏾‍♀ ️By the way: If you’re looking for cool & open-source projects in Go, check out NicoNex’s programming language, Tau, and if you’re into building Telegram bots using Go, Echotron is the way.

--

--