Introduction:
In this article, we'll explore the process of building an HTTP server using Golang, from the initial setup of a blank project to implementing routes and utilizing dependency injection for a cleaner and more maintainable codebase.
Setting Up the Project:
To kick things off, let's start by creating a new Golang project in Visual Studio Code. Navigate to a blank folder, open VS Code, and create a file named "main.go." Begin with the standard package declaration and a simple "Hello, World!" output using the fmt package.
package main
import "fmt"
func main() {
fmt.Println("Hello, Go!")
}
Spinning Up the Basic HTTP Server:
Moving on, we'll evolve our project into an HTTP server. Golang provides a straightforward way to accomplish this, as demonstrated by the following code snippet:
package main
import (
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, Go!")
})
http.ListenAndServe(":3000", nil)
}
This basic setup responds with "Hello, Go!" when accessing the root URL. However, the absence of defined routes results in a 404 page.
Cleaning Up with Gorilla Mux:
To enhance the structure of our server, we'll employ the Gorilla Mux package for handling routes. First, initialize the Go module and add the Gorilla Mux package.
go mod init github.com/your-username/your-project
go get github.com/gorilla/mux
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, Go!")
})
http.Handle("/", router)
http.ListenAndServe(":3000", nil)
}
Implementing Dependency Injection:
To further enhance our project's structure, we'll implement dependency injection by creating a new file named "api.go." This new file introduces a more organized approach to managing the server instance.
package main
import (
"net/http"
"github.com/gorilla/mux"
)
// API struct represents the API server.
type APIServer struct {
address string
}
// NewAPI initializes a new APIServer instance.
func NewAPIServer(address string) *APIServer{
return &APIServer{
address: address,
}
}
// Run starts the API server.
func (a *APIServer) Run() error {
router := mux.NewRouter()
router.HandleFunc("/hello", a.handleGreet)
fmt.Printf("Server starting on address %s", a.addr)
return http.ListenAndServe(a.address, router)
}
With this approach, we have a more modular and organized project structure.
Now let's embed our handler into the API to handle our "/hello" route.
Let's create a new file named "routes.go"
func (a *APIServer) handleGreet(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Method not supported"))
return
}
The main.go file now looks cleaner:
package main
func main() {
api := NewAPIServer(":3000")
if err := api.Run(); err != nil {
fmt.Println("Error starting the server:", err)
}
}
Conclusion:
In this article, we've progressed from a basic "Hello, World!" program to building a more organized Golang HTTP server. By incorporating Gorilla Mux for routing and implementing dependency injection, our project becomes scalable, modular, and easier to maintain.
This was a mere glimpse of what we did in this Udemy course ofΒ mine:
REST API using GoLang, PostgreSQL, Keycloak, Docker
I will see you in the next article. Until then, scatter.
Now you know where to find me:
LinkedIn
YouTube
Github
Udemy
Top comments (0)