Web servers are what makes the online world work and in this tutorial, you’ll dive headfirst into creating your own Go HTTP web server in a step-by-step manner.
Go is an extremely versatile programming language. You can do system programming in Go or even create highly interactive web applications. Due to its wide variety of applications, Go is seeing a lot of industry adoption over the years.
Let’s dive into the task of creating a simple web server in Go. In the next sections, we will learn how to set up a simple Go web server for beginners.
1 – A Brief Intro to Go
For creating your own Go HTTP web server, it’s crucial to grasp the pivotal role that Go plays in modern web development.
At its core, Go is engineered for efficiency and speed. This makes it a top choice for building highly concurrent web applications.
Also, over the years, Go has attracted a thriving community supported by a rich standard library.
In case this is your first foray into Go, I recommend going through this post on starting with Go where I explain how you can set it up for your development machine. I also talk about setting up a Go development environment for easy usage.
2 – Creating an HTTP Web Server with Go
With Go installed and ready on your system, it’s time to start creating our web server that can handle HTTP requests.
But what is a web server?
A web server acts as the gateway between your laptop or mobile device and an application running somewhere on the internet. From an application’s perspective, a web server handles incoming requests from millions of users like you and I and responds with the data needed.
To get started, create a project directory and execute the below command:
$ go mod init webserver
This command will create a file named go.mod
within the project directory.
module webserver
go 1.20
Next, you can create a file main.go
with the below code:
package main
import (
"fmt"
"net/http"
)
func handleRequest(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
message := fmt.Sprintf("You requested: %s", path)
fmt.Fprintf(w, message)
}
func main() {
http.HandleFunc("/", handleRequest)
fmt.Println("Server is listening on port 8080...")
http.ListenAndServe(":8080", nil)
}
Let’s understand what is going on over here in more detail:
- At the very beginning, we import the
net/http
package that contains all the functionality necessary to create a basic web server in Go.
- The
handleRequest
function takes two parameters –w http.ResponseWriter
for sending the responses andr *http.Request
for the incoming request object. - For demo purpose, we extract the
r.URL.path
property of the request object. This is basically the part of the URL that follows the domain. - Next, we generate a response message that includes the path. For example, “You requested: /test”.
- Moving on, we use the
fmt.Fprintf()
function to write the message to the response writer. This function takes the response writer instance and the message as input. - In the
main()
function of the program, the first linehttp.HandleFunc()
sets up an HTTP route or endpoint and the function that should handle the request. It specifies when a user accesses the root URL of the web server, the following function should be executed. - In this case, it’s the
handleRequest()
function. - Lastly, we call the
ListenAndServe()
method on thehttp
object to start the webserver on port 8080.
3 – Additional Points
Few important points to discuss about the code we just wrote:
Point#1
In the statement http.ListenAndServe(":8080", nil)
, we specify a colon before the port number. This indicates that the server should bind to all available network interfaces on the specific port.
In simple terms, we are telling our Go HTTP Web Server to listen on port 8080 for incoming requests from any available network interface on the local machine. For example, requests coming from http://localhost:8080
or http://127.0.0.1:8080
in your web browser.
Point#2
The nil
in ListenAndServe
is used as the value for the handler parameter for processing incoming HTTP requests.
In this case, passing nil
indicates you want to use the default HTTP server mux provided by the http
package.
Point#3
The ‘*’ (asterisk) in *http.Request
indicates that http.Request
is a pointer to a struct type.
- Pointers are good for the overall efficiency of handling the request. An HTTP request can contain a lot of data including headers, URL information and a request body. If you pass the entire request data by value, it would create a copy of all that data every time you passed it to a function.
- It is also possible to modify the HTTP request data during the request lifecycle. Using a pointer allows us to work with the same request object throughout the lifecycle.
Conclusion
That’s all for this post.
In this post, we completed a step-by-step tutorial on creating an HTTP Webserver in Go from scratch.
It also involved exploring the fundamentals of Go, setting up a dev environment and getting into the concepts of web servers. Moreover, you learned about the importance of pointers in http.Request
and the default server handler.
In the next post, you can learn how to handle routing in a Go web server.
If you have any queries about this post, please feel free to mention them in the comments section below.
0 Comments