📝 Exercise: Create a Basic Web Server in Go

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.

🛠Your Task :

1️⃣ Set up a basic Go web server that listens on port 8080.

2️⃣ Define multiple routes with the following functionalities :

💡 Hints :

Solution :


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)
}

                

📌 Explanation of the Solution :

✅ How to Run the Code :

🚀 Challenge (Optional, for Advanced Practice) :

🚀 Advanced Solution :


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)
}

                

📌 Explanation of the Advanced Features :

✅ How to Run the Code :

🚀 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! 🙌


☕ Buy me a coffee