Skip to content

Go Mini Projects — Build Real-World Go Applications from Scratch

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about Go Mini Projects. We cover key concepts, practical examples, and best practices to help you master this topic.

Go mini projects build a REST API server, CLI task manager, URL shortener, and file server applying slices, goroutines, HTTP, and JSON skills.

What You'll Learn

  • REST API with Gin
  • CLI task manager with cobra
  • URL shortener with in-memory storage
  • File server with middleware

Why It Matters

Projects reinforce learning. These projects mirror tools used at Docker, Kubernetes, and DodaTech.

Real-World Use

Internal REST APIs, DevOps automation tools, URL management services, static file serving.

REST API Server

package main

import (
    "github.com/gin-gonic/gin"
)

type Task struct {
    ID   int    `json:"id"`
    Name string `json:"name" binding:"required"`
    Done bool   `json:"done"`
}

var tasks = []Task{}
var nextID = 1

func main() {
    r := gin.Default()

    r.GET("/tasks", func(c *gin.Context) {
        c.JSON(200, tasks)
    })

    r.POST("/tasks", func(c *gin.Context) {
        var task Task
        if err := c.ShouldBindJSON(&task); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }
        task.ID = nextID
        nextID++
        tasks = append(tasks, task)
        c.JSON(201, task)
    })

    r.DELETE("/tasks/:id", func(c *gin.Context) {
        id, _ := strconv.Atoi(c.Param("id"))
        for i, t := range tasks {
            if t.ID == id {
                tasks = append(tasks[:i], tasks[i+1:]...)
                c.JSON(200, gin.H{"deleted": id})
                return
            }
        }
        c.JSON(404, gin.H{"error": "not found"})
    })

    r.Run(":8080")
}

CLI Task Manager

package main

import "github.com/spf13/cobra"

var tasks []string

func main() {
    root := &cobra.Command{Use: "task"}

    root.AddCommand(&cobra.Command{
        Use: "add [task]",
        Run: func(cmd *cobra.Command, args []string) {
            tasks = append(tasks, args[0])
            fmt.Printf("Added: %s\n", args[0])
        },
    })

    root.AddCommand(&cobra.Command{
        Use: "list",
        Run: func(cmd *cobra.Command, args []string) {
            for i, t := range tasks {
                fmt.Printf("%d. %s\n", i+1, t)
            }
        },
    })

    root.Execute()
}

URL Shortener

package main

import (
    "crypto/rand"
    "encoding/hex"
    "net/http"
    "sync"
)

type Store struct {
    mu     sync.RWMutex
    urls   map[string]string
}

func (s *Store) Shorten(original string) string {
    s.mu.Lock()
    defer s.mu.Unlock()
    bytes := make([]byte, 3)
    rand.Read(bytes)
    key := hex.EncodeToString(bytes)
    s.urls[key] = original
    return key
}

func (s *Store) Resolve(key string) (string, bool) {
    s.mu.RLock()
    defer s.mu.RUnlock()
    val, ok := s.urls[key]
    return val, ok
}

File Server

func main() {
    r := gin.Default()

    r.Static("/static", "./public")

    r.POST("/upload", func(c *gin.Context) {
        file, _ := c.FormFile("file")
        dst := filepath.Join("./uploads", file.Filename)
        c.SaveUploadedFile(file, dst)
        c.JSON(200, gin.H{"path": dst})
    })

    r.GET("/download/:name", func(c *gin.Context) {
        name := c.Param("name")
        c.File(filepath.Join("./uploads", name))
    })

    r.Run(":8080")
}
Topic Description Link
Go Ecosystem Community and tools {{< ref "46-ecosystem" >}}
Go Web Frameworks Gin, Echo, Fiber {{< ref "40-web-frameworks" >}}
Ruby Mini Projects Compare Ruby projects Ruby

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro

Home Browse Go