Building a To-Do List Web Application with Golang, Gin, and MySQL

Building a To-Do List Web Application with Golang, Gin, and MySQL

In this tutorial, we'll build a simple to-do list web application using Golang, the Gin framework, and MySQL. This app will allow users to create, read, update, and delete to-do items.

Prerequisites

Before we begin, make sure you have the following installed:

  1. Golang
  2. MySQL
  3. A code editor (like VS Code)

Setting Up the Project

Step 1: Create a New Project

First, let's create a new directory for our project and initialize a Go module.

mkdir todolist
cd todolist
go mod init todolist

Step 2: Install Dependencies

We need to install the Gin framework and a MySQL driver.

go get github.com/gin-gonic/gin
go get github.com/jinzhu/gorm
go get github.com/jinzhu/gorm/dialects/mysql

Step 3: Set Up MySQL

Create a database named todolist in MySQL. You can do this using the MySQL command line or a tool like phpMyAdmin.

CREATE DATABASE todolist;
USE todolist;
CREATE TABLE todos (
id INT AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
completed BOOLEAN NOT NULL DEFAULT FALSE,
PRIMARY KEY (id)
);

Building the Application

Step 4: Project Structure

Create the following files in your project:

todolist/
├── main.go
├── models/
│ └── todo.go
└── handlers/
└── todo.go

Step 5: Define the Todo Model

In models/todo.go, define the Todo model using GORM.

package models

import "github.com/jinzhu/gorm"

type Todo struct
{
gorm.Model
Title string `json:"title"`
Completed bool `json:"completed"`

}

Step 6: Database Connection

In main.go, set up the database connection and initialize the Gin server.

package main

import (
"todolist/models"
"todolist/handlers"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"log"

)

func main() {
db, err := gorm.Open("mysql", "root:password@/todolist?charset=utf8&parseTime=True&loc=Local")
if err != nil {
log.Fatal(err)
}
defer db.Close()

db.AutoMigrate(&models.Todo{})

r := gin.Default()
r.GET("/todos", handlers.GetTodos(db))
r.POST("/todos", handlers.CreateTodo(db))
r.PUT("/todos/:id", handlers.UpdateTodo(db))
r.DELETE("/todos/:id", handlers.DeleteTodo(db))

r.Run(":8080")
}

Step 7: Create Handlers

In handlers/todo.go, create the CRUD handlers for the to-do list.

package handlers

import (
"todolist/models"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"net/http"

)

func GetTodos(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
var todos []models.Todo
if err := db.Find(&todos).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, todos)
}
}

func CreateTodo(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
var todo models.Todo
if err := c.ShouldBindJSON(&todo); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := db.Create(&todo).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, todo)
}
}

func UpdateTodo(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("id")
var todo models.Todo
if err := db.Where("id = ?", id).First(&todo).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Todo not found"})
return
}
if err := c.ShouldBindJSON(&todo); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := db.Save(&todo).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, todo)
}
}

func DeleteTodo(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("id")
if err := db.Where("id = ?", id).Delete(&models.Todo{}).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.Status(http.StatusNoContent)
}
}

Running the Application

Step 8: Start the Server

Run your application by executing the following command in your terminal:

go run main.go

Your server should be running on http://localhost:8080.

Step 9: Testing the Endpoints

You can use tools like Postman or curl to test your API endpoints.

  • Get all to-dos:curl http://localhost:8080/todos
  • Create a new to-do:curl -X POST http://localhost:8080/todos -H "Content-Type: application/json" -d '{"title": "Learn Golang"}'
  • Update a to-do:curl -X PUT http://localhost:8080/todos/1 -H "Content-Type: application/json" -d '{"title": "Learn Gin", "completed": true}'
  • Delete a to-do:curl -X DELETE http://localhost:8080/todos/1

Conclusion

You've now built a basic CRUD web application using Golang, the Gin framework, and MySQL. This tutorial covered setting up the project, connecting to a MySQL database, and creating endpoints to manage to-do items. Happy coding!

Read more