Logo

Command Palette

Search for a command to run...

Blog
Next

How to Create a Simple HTTP Server in Go

Build a basic Go HTTP server with CRUD routes, handlers, and safe concurrency using sync.RWMutex.

Go makes it incredibly easy to build fast, concurrent, and scalable web servers with minimal code. In this tutorial, we'll walk through how to create a basic HTTP server that handles CRUD operations for users including adding, retrieving, and deleting them.

Step 1: Setting Up the Project

Start by creating a new Go file, for example, main.go, and add the following package declaration and imports:

package main
 
import (
  "encoding/json"
  "fmt"
  "net/http"
  "strconv"
  "sync"
)

Here:

  • net/http provides tools for building web servers.
  • encoding/json allows you to work with JSON data.
  • strconv helps convert strings to numbers.
  • sync is used for safe concurrent access to shared data.

Step 2: Define a User Type and Cache

We'll create a simple User struct and use a map to store users in memory.

type User struct {
  Name string `json:"name"`
}
 
var userCache = make(map[int]User)
var cacheMutex sync.RWMutex

The cacheMutex ensures safe read/write access to userCache since multiple requests could come in at once.

Step 3: Create the Server and Routes

We'll use http.NewServeMux() to create a request multiplexer that directs incoming requests to their corresponding handlers.

func main() {
  mux := http.NewServeMux()
  fmt.Println("Server is running on port 8080")

1. Root Endpoint

A simple handler to test if your server is running:

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte("Hello World"))
})

2. POST /users: Create a New User

mux.HandleFunc("POST /users", func(w http.ResponseWriter, r *http.Request) {
  var user User
  err := json.NewDecoder(r.Body).Decode(&user)
  if err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
    return
  }
  if user.Name == "" {
    http.Error(w, "Name is required", http.StatusBadRequest)
    return
  }
 
  cacheMutex.Lock()
  userCache[len(userCache)+1] = user
  cacheMutex.Unlock()
  w.Write([]byte("User Created"))
})

This handler reads the JSON body, validates it, and stores the user in the cache.

3. GET /users/{id}: Retrieve a User by ID

mux.HandleFunc("GET /users/{id}", func(w http.ResponseWriter, r *http.Request) {
  id, err := strconv.Atoi(r.PathValue("id"))
  if err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
    return
  }
 
  cacheMutex.RLock()
  user, ok := userCache[id]
  cacheMutex.RUnlock()
  if !ok {
    http.Error(w, "User not found", http.StatusNotFound)
    return
  }
  w.Header().Set("Content-Type", "application/json")
  j, err := json.Marshal(user)
  if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
  }
  w.WriteHeader(http.StatusOK)
  w.Write(j)
})

This route fetches a user by ID, converts it to JSON, and returns it.

4. DELETE /users/{id}: Delete a User

mux.HandleFunc("DELETE /users/{id}", func(w http.ResponseWriter, r *http.Request) {
  id, err := strconv.Atoi(r.PathValue("id"))
  if err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
    return
  }
 
  if _, ok := userCache[id]; !ok {
    http.Error(w, "User not found", http.StatusNotFound)
    return
  }
  cacheMutex.Lock()
  delete(userCache, id)
  cacheMutex.Unlock()
  w.WriteHeader(http.StatusNoContent)
  w.Write([]byte("User Deleted"))
})

This handler deletes a user from the cache safely.

Step 4: Start the Server

Finally, start the server by listening on port 8080:

http.ListenAndServe(":8080", mux)
}

Now, run the program:

go run main.go

Visit http://localhost:8080 — you should see Hello World!

Conclusion

With just a few lines of Go, you've built:

  • A basic HTTP server
  • CRUD endpoints for managing users
  • Safe concurrent access with sync.RWMutex

This example is a great starting point for learning how to build REST APIs in Go. From here, you can expand to using databases, authentication, and middleware for a full production setup.

The source code is available at: github.com/satyawaniaman/http-server-go