In this exercise, you will build a simple HTTP web server in Go. This will help you practice handling HTTP requests, defining routes, and serving responses.
If you want to learn more about the Go HTTP server, it is recommended to read this tutorial before starting this exercise.
{
"message": "Hello from the API!"
}
http.HandleFunc()
to define routes.fmt.Fprintf()
for simple text responses.encoding/json
and set the Content-Type to "application/json"
.(name in /greet)
, user.URL.Query().Get("name")
.http.ListenAndServe(":8080", nil)
to start the server.
package main
import (
"encoding/json"
"fmt"
"net/http"
)
// Message struct for JSON response
type Message struct {
Message string `json:"message"`
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome to my Go Web Server!")
}
func aboutHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "This is a basic HTTP server built in Go.")
}
func apiMessageHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") // Set response type to JSON
response := Message{Message: "Hello from the API!"}
json.NewEncoder(w).Encode(response) // Encode and send JSON response
}
func greetHandler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name") // Get 'name' parameter from URL
if name == "" {
name = "Guest"
}
fmt.Fprintf(w, "Hello, %s!", name)
}
func main() {
// Define routes
http.HandleFunc("/", homeHandler)
http.HandleFunc("/about", aboutHandler)
http.HandleFunc("/api/message", apiMessageHandler)
http.HandleFunc("/greet", greetHandler)
// Start the server on port 8080
fmt.Println("Server is running on http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
homeHandler
→ Handles / route, returns a simple text response.aboutHandler
→ Handles /about, returns a brief description.apiMessageHandler
→ Handles /api/message, returns a JSON response.greetHandler
→ Handles /greet?name=John, extracts the name parameter and responds accordingly.http.ListenAndServe(":8080", nil)
→ Starts the server on port 8080.go run main.go
http://localhost:8080/
→ Displays "Welcome to my Go Web Server!"http://localhost:8080/about
→ Displays "This is a basic HTTP server built in Go."http://localhost:8080/api/message
→ Returns {"message": "Hello from the API!"}http://localhost:8080/greet?name=John
→ Displays "Hello, John!"http://localhost:8080/greet
→ Displays "Hello, Guest!"
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
)
// Message struct for JSON response
type Message struct {
Message string `json:"message"`
}
// Home route
func homeHandler(w http.ResponseWriter, r *http.Request) {
logRequest(r)
fmt.Fprintf(w, "Welcome to my Go Web Server!")
}
// About route
func aboutHandler(w http.ResponseWriter, r *http.Request) {
logRequest(r)
fmt.Fprintf(w, "This is a basic HTTP server built in Go.")
}
// API route - JSON response
func apiMessageHandler(w http.ResponseWriter, r *http.Request) {
logRequest(r)
w.Header().Set("Content-Type", "application/json")
response := Message{Message: "Hello from the API!"}
json.NewEncoder(w).Encode(response)
}
// Greet route - reads a query parameter
func greetHandler(w http.ResponseWriter, r *http.Request) {
logRequest(r)
name := r.URL.Query().Get("name")
if name == "" {
name = "Guest"
}
fmt.Fprintf(w, "Hello, %s!", name)
}
// 404 Not Found handler for unknown routes
func notFoundHandler(w http.ResponseWriter, r *http.Request) {
logRequest(r)
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "404 Not Found - The requested page does not exist.")
}
// Middleware for logging requests
func logRequest(r *http.Request) {
log.Printf("[%s] %s %s", r.RemoteAddr, r.Method, r.URL.Path)
}
// Setup logging to a file
func setupLogging() {
logFile, err := os.OpenFile("server.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Println("Could not open log file, logging to standard output.")
return
}
log.SetOutput(logFile)
}
func main() {
// Setup logging
setupLogging()
// Define routes
http.HandleFunc("/", homeHandler)
http.HandleFunc("/about", aboutHandler)
http.HandleFunc("/api/message", apiMessageHandler)
http.HandleFunc("/greet", greetHandler)
// Serve static files (e.g., index.html, style.css)
fs := http.FileServer(http.Dir("./static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
// Handle unknown routes (404)
http.HandleFunc("/404", notFoundHandler)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" && r.URL.Path != "/about" && r.URL.Path != "/api/message" && r.URL.Path != "/greet" {
notFoundHandler(w, r)
}
})
// Start the server
fmt.Println("Server is running on http://localhost:8080")
log.Println("Server started on port 8080")
http.ListenAndServe(":8080", nil)
}
http.FileServer()
.404 Not Found
.log.Printf()
) :
log.SetOutput()
.go run main.go
http://localhost:8080/
→ Home pagehttp://localhost:8080/about
→ About pagehttp://localhost:8080/api/message
→ JSON APIhttp://localhost:8080/greet?name=John
→ "Hello, John!"http://localhost:8080/static/index.html
→ Serves index.htmlhttp://localhost:8080/unknown
→ Returns 404 Not Found🚀 Thank you for working through these exercises! If you find this content valuable and want to support my work, a coffee would be greatly appreciated! ☕😊
💻 I am a freelance web developer, and I personally create and maintain this website. Any support would help me improve and expand it further! 🙌