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
 
antoniofromlitlyx profile image
Antonio

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
 
aadarsh-nagrath profile image
Aadarsh Nagrath

Good one

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
 
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.