How to Get Started with a CRUD Web Server in Go

Stuti Pradhan / 21 September 2024
4 min read

Getting Started with a CRUD Web Server in Go

Go (or Golang) is a powerful, statically typed language known for its simplicity and performance, making it an excellent choice for building web servers. In this article, we'll walk through the process of setting up a basic CRUD (Create, Read, Update, Delete) web server in Go.


1. Setting Up Your Go Environment

Before you start coding, ensure you have Go installed on your machine. You can download and install Go from the official website. Once installed, verify the installation by running:

go version

This should display the version of Go installed on your machine.

Next, set up your project directory:

mkdir go-crud-server
cd go-crud-server

Create a main.go file where you'll write your server code:

touch main.go

2. Setting Up a Basic HTTP Server

First, you'll want to set up a basic HTTP server in Go. Open main.go and add the following code:

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Welcome to the CRUD server!")
    })

    fmt.Println("Server is running on port 8080...")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

This code sets up a simple server that listens on port 8080 and responds with a welcome message. Run the server with:

go run main.go

You can visit http://localhost:8080 in your browser to see the message.


3. Implementing CRUD Operations

Now, let's implement the CRUD operations for a simple Book resource. We'll start by defining the Book struct:

type Book struct {
    ID     string `json:"id"`
    Title  string `json:"title"`
    Author string `json:"author"`
}

We'll also need to create a slice to store our books in memory:

var books []Book

Create Operation

To add a new book, we'll create a handler that accepts a POST request:

func createBook(w http.ResponseWriter, r *http.Request) {
    var book Book
    json.NewDecoder(r.Body).Decode(&book)
    book.ID = strconv.Itoa(len(books) + 1)
    books = append(books, book)
    json.NewEncoder(w).Encode(book)
}

Read Operation

For the read operation, we’ll implement two handlers: one to get all books and another to get a specific book by its ID.

func getBooks(w http.ResponseWriter, r *http.Request) {
    json.NewEncoder(w).Encode(books)
}

func getBook(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    for _, item := range books {
        if item.ID == params["id"] {
            json.NewEncoder(w).Encode(item)
            return
        }
    }
    json.NewEncoder(w).Encode(&Book{})
}

Update Operation

The update operation will allow you to modify an existing book's details:

func updateBook(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    for index, item := range books {
        if item.ID == params["id"] {
            books = append(books[:index], books[index+1:]...)
            var book Book
            json.NewDecoder(r.Body).Decode(&book)
            book.ID = params["id"]
            books = append(books, book)
            json.NewEncoder(w).Encode(book)
            return
        }
    }
    json.NewEncoder(w).Encode(books)
}

Delete Operation

Finally, we'll implement the delete operation to remove a book from the list:

func deleteBook(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    for index, item := range books {
        if item.ID == params["id"] {
            books = append(books[:index], books[index+1:]...)
            break
        }
    }
    json.NewEncoder(w).Encode(books)
}

4. Routing with Gorilla Mux

To handle routing more efficiently, we'll use the gorilla/mux package. Install it using:

go get -u github.com/gorilla/mux

Then, update your main.go to use mux for routing:

func main() {
    router := mux.NewRouter()

    // Routes
    router.HandleFunc("/books", getBooks).Methods("GET")
    router.HandleFunc("/books/{id}", getBook).Methods("GET")
    router.HandleFunc("/books", createBook).Methods("POST")
    router.HandleFunc("/books/{id}", updateBook).Methods("PUT")
    router.HandleFunc("/books/{id}", deleteBook).Methods("DELETE")

    fmt.Println("Server is running on port 8080...")
    log.Fatal(http.ListenAndServe(":8080", router))
}

With this setup, your CRUD server can handle requests to create, read, update, and delete Book records.


Conclusion

You've now built a simple CRUD web server in Go! This foundational example can be expanded with a database connection, middleware, authentication, and more, depending on your application's requirements. Go's simplicity and efficiency make it an excellent choice for building scalable web services.