DEV Community

Cover image for Creating a CRUD App With Go
Ethan
Ethan

Posted on • Originally published at ethan-dev.com

Creating a CRUD App With Go

Introduction

Hello! ๐Ÿ˜Ž

In this tutorial I will show you how to build a CRUD app using the Go programming language. By the end, you'll have a fully functioning CRUD (Create, Read, Update, Delete) app running locally. Let's get started.


Requirements

  • Go installed
  • Basic understanding of Go

Setting up the project

Create a new directory for the project and navigate into it:



mkdir crud-app && cd crud-app


Enter fullscreen mode Exit fullscreen mode

Next we will initialize the go module and install the dependencies:



go mod init go-crud-app
go get -u github.com/gorilla/mux


Enter fullscreen mode Exit fullscreen mode

Now that the project and required packages are installed we can start working on the application. ๐Ÿ˜ธ


Coding the Application

Create a new file called "main.go" and import the following:



package main

import (
    "encoding/json"
    "log"
    "net/http"
    "strconv"
    "github.com/gorilla/mux"
)


Enter fullscreen mode Exit fullscreen mode
  • encoding/json: For encoding and decoding JSON data
  • log: For logging errors
  • net/http: For building the HTTP server
  • strconv: For converting strings to integers
  • github.com/gorilla/mux: A popular package for routing HTTP requests

Next we define our global variables like so:



var memos []Memo
var idCounter int


Enter fullscreen mode Exit fullscreen mode
  • memos: A slice that will store all our memos
  • idCounter: A counter to keep track of memo IDs

Now we need to create a struct to define a memo:



type Memo struct {
    ID      int    `json:"id"`
    Title   string `json:"title"`
    Content string `json:"content"`
}


Enter fullscreen mode Exit fullscreen mode

Next we will create handlers for each of the CRUD operations, the first one will handle create a new memo:



func createMemo(w http.ResponseWriter, r *http.Request) {
    var memo Memo
    json.NewDecoder(r.Body).Decode(&memo)
    idCounter++
    memo.ID = idCounter
    memos = append(memos, memo)
    json.NewEncoder(w).Encode(memo)
}


Enter fullscreen mode Exit fullscreen mode
  • Decode the JSON request body into a memo struct
  • Increment the idCounter and assign a new memo
  • Append the new memo to the memos slice
  • Encode and return the created memo as a JSON response

The next function will handle getting all the memos:



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


Enter fullscreen mode Exit fullscreen mode
  • Encode and return the memos slice as a JSON response

Below is the handler to handle getting a single memo:



func getMemo(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    id, _ := strconv.Atoi(params["id"])

    for _, memo := range memos {
        if memo.ID == id {
            json.NewEncoder(w).Encode(memo)
            return
        }
    }

    http.Error(w, "Memo not found", http.StatusNotFound)
}


Enter fullscreen mode Exit fullscreen mode
  • Retrieve the id from the URL parameters
  • Search for the memo with the matching ID in the memos slice
  • Return the memo if found, otherwise returns a 404 error

The next function handles updating a memo:



func updateMemo(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    id, _ := strconv.Atoi(params["id"])

    for i, memo := range memos {
        if memo.ID == id {
            json.NewDecoder(r.Body).Decode(&memo)
            memo.ID = id
            memos[i] = memo
            json.NewEncoder(w).Encode(memo)
            return
        }
    }

    http.Error(w, "Memo not found", http.StatusNotFound)
}


Enter fullscreen mode Exit fullscreen mode
  • Retrieve the id from the URL parameters
  • Search for the memo with the matching ID in the memos slice
  • Decode the JSON request body into the found memo and update it
  • Return the updated memo as a JSON response or return a 404 error if not found

Lastly we need a function to handle the delete operation:



func deleteMemo(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    id, _ := strconv.Atoi(params["id"])

    for i, memo := range memos {
        if memo.ID == id {
            memos = append(memos[:i], memos[i+1:]...)
            json.NewEncoder(w).Encode("The memo was deleted successfully")
            return
        }
    }

    http.Error(w, "Memo not found", http.StatusNotFound)
}


Enter fullscreen mode Exit fullscreen mode
  • Retrieve the id from the URL parameters
  • Search for the memo with the matching ID in the memos slice
  • Delete the memo by removing it from the slice
  • Return a success message or a 404 error if the memo is not found

Next we need to set up the routes to handle each of the CRUD requests:



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

    router.HandleFunc("/memos", createMemo).Methods("POST")
    router.HandleFunc("/memos", getMemos).Methods("GET")
    router.HandleFunc("/memos/{id}", getMemo).Methods("GET")
    router.HandleFunc("/memos/{id}", updateMemo).Methods("PUT")
    router.HandleFunc("/memos/{id}", deleteMemo).Methods("DELETE")

    log.Fatal(http.ListenAndServe(":8000", router))
}


Enter fullscreen mode Exit fullscreen mode
  • Initialize a new router using mux.NewRouter
  • Define routes for each CRUD operation and map them to the respective handlers
  • Start the HTTP server on port 8000

Finally we need to implement the main function, as so:



func main() {
    memos = append(memos, Memo{ID: 1, Title: "First memo", Content: "Hello World"})
    idCounter = 1
    initializeRouter()
}


Enter fullscreen mode Exit fullscreen mode
  • Initialize the memos slice with a sample memo
  • Set the idCounter to 1
  • Call the previous initializeRouter function to start the server

Done! Now we can move onto testing the application. ๐Ÿ˜†


Testing the Application

First we need to start the server before we can make requests to it, this is done via the following command:



go run main.go


Enter fullscreen mode Exit fullscreen mode

Now we can use the following CURL commands to test each of the endpoints.

Create a memo:



curl -X POST -d '{"title":"New Memo","content":"This is a new memo."}' -H "Content-Type: application/json" http://localhost:8000/memos


Enter fullscreen mode Exit fullscreen mode

Get all memos:



curl http://localhost:8000/memos


Enter fullscreen mode Exit fullscreen mode

Get a memo by it's ID:



curl http://localhost:8000/memos/1


Enter fullscreen mode Exit fullscreen mode

Update a memo:



curl -X PUT -d '{"title":"Updated Memo","content":"This is an updated memo."}' -H "Content-Type: application/json" http://localhost:8000/memos/1


Enter fullscreen mode Exit fullscreen mode

Delete a memo:



curl -X DELETE http://localhost:8000/memos/1


Enter fullscreen mode Exit fullscreen mode

Feel free to change the contents and have a play around with it. ๐Ÿ‘€


Conclusion

In this tutorial I have shown how to implement a CRUD application using the Go programming language, I'm having a lot of fun learning Go and I hope this tutorial has helped you.

As always you can find the sample code on my Github:
https://github.com/ethand91/go-crud

Happy Coding! ๐Ÿ˜Ž


Like my work? I post about a variety of topics, if you would like to see more please like and follow me.
Also I love coffee.

โ€œBuy Me A Coffeeโ€

If you are looking to learn Algorithm Patterns to ace the coding interview I recommend the [following course](https://algolab.so/p/algorithms-and-data-structure-video-course?affcode=1413380_bzrepgch

Top comments (10)

Collapse
 
litlyx profile image
Antonio | CEO at Litlyx.com

Great! Im Listening a lot of positive things on Golang in this period. Definitely to be learned! There is some power in this lang, i really want to learn the tips and tricks.

Thanks a lot for sharing this Entry level CRUD app for us all.

Antonio, CEO at Litlyx

Collapse
 
ethand91 profile image
Ethan

Your welcome :)
I'm glad you like it

Collapse
 
developedbyjk profile image
developedbyjk

Interesting ๐Ÿง  Never Tried Go Though ๐Ÿค”๐Ÿ’ญ

Collapse
 
ethand91 profile image
Ethan

I'm also new to it, it's different from the other languages but it is fun to learn

Collapse
 
bladearya profile image
Amit Kumar Rout

I am studying GOLANG currently. This will help in building projects.

Collapse
 
ethand91 profile image
Ethan

Good luck in your studies :)

Collapse
 
aadarsh-nagrath profile image
Aadarsh Nagrath

Good one

Collapse
 
ethand91 profile image
Ethan

Thanks for the lovely comment <3 I'll do my best! :)

Collapse
 
sysmat profile image
Sysmat
Collapse
 
douglas_taylor_35c9541ef8 profile image
Douglas Taylor

pizdez

Some comments may only be visible to logged-in visitors. Sign in to view all comments.