Creating an HTTP server in Go
June 18, 2024
Introduction
This tutorial would show you how to create a basic http server in Go lang. For this we’ll need Go 1.22 as it offers built-in enhanced routing that would save us time in thinking what framework should we use.
Folder Structure
go.modgo.workmain.go- handlers/
home.goarticles.go
Initilizing Project
Create project.
$ mkdir http-server; cd http-server;Initialize project.
$ go mod init http-server;
$ go work init .; # enable workspacesCreating the router
NewServeMux would return a ServeMux that would serve us our router for the application.
Let’s create barebone http server first to try it out.
package main
import (
"fmt"
"log"
"net/http"
)
func HomeRoute(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World!")
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/{$}", HomeRoute) // <--- `/{$}` only matches `/`
err := http.ListenAndServe(":3000", mux)
if err != nil {
log.Fatalln("Cannot run the server", err)
}
}Method Specific Route
To filter specific request method to a route, we could use a prefix to identify the target request method.
- mux.HandleFunc("/{$}", HomeRoute)
+ mux.HandleFunc("GET /{$}", HomeRoute)Learn more about ServeMux patterns
Testing the application…
GET method has response
$ curl localhost:3000
Hello World!POST method throws an error
$ curl -XPOST localhost:3000
Method Not AllowedGetting Path Value
One of the biggest game changer introduced in Go 1.22 is the ability to read url paths.
func ArticlesRoute(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Reading article", r.PathValue("article"))
}Register the path:
mux.HandleFunc("/articles/{article}", ArticlesRoute)What do we have now?
package main
import (
"fmt"
"log"
"net/http"
)
func HomeRoute(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World!")
}
+ func ArticlesRoute(w http.ResponseWriter, r *http.Request) {
+ fmt.Fprintln(w, "Reading article", r.PathValue("article"))
+ }
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /{$}", HomeRoute)
+ mux.HandleFunc("/articles/{article}", ArticlesRoute)
err := http.ListenAndServe(":3000", mux)
if err != nil {
log.Fatalln("Cannot run the server", err)
}
}Testing the new route
$ curl localhost:3000/articles/hello-world
Reading article hello-worldOrganizing our project
To better organize our code, we’ll create a new module.
mkdir handlers;Then move our route to each separate module inside handlers
// ./handlers/home.go
package handlers
import (
"fmt"
"net/http"
)
func HomeRoute(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World!")
}// ./handlers/articles.go
package handlers
import (
"fmt"
"net/http"
)
func ArticlesRoute(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Reading article", r.PathValue("article"))
}Update our main.go to read the handlers submodule.
package main
import (
"http-server/handlers"
"log"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /{$}", handlers.HomeRoute)
mux.HandleFunc("/articles/{article}", handlers.ArticlesRoute)
err := http.ListenAndServe(":3000", mux)
if err != nil {
log.Fatalln("Cannot run the server", err)
}
}Conclusion
Here we have learned about how to create a basic HTTP server using Go and how to utilize. Hoping that this tutorial helped kickstart your dream project in Go.
To see the full project in this tutorial click here.