10 Project Ideas To Learn Golang In 2024



10 Project Ideas To Learn Golang In 2024

Are you a newbie, learning golang and lacking the motivation to practice what you have been taught? Well, there is no need to worry about that! I have compiled some of the most popular mini-projects that one could build. You may also want to take a look at my sample codes as well as put your twist on them just to display how imaginative you are. The mini-projects are for all levels of learners such as beginners, intermediate and advanced learners.

To begin with, make sure you have Golang installed on your machine and have a basic understanding of it. If you are new to the language, then you can follow my Golang tutorial step by step to get started.

Table of Contents

Now let us begin with what’s new today in our blog and have a glance at some golang project ideas.

Building Dynamic Web Applications

Web Applications

Web applications are web browser-based software programs that permit online interaction and task performance. They include many different things, such as social media sites like Facebook or e-commerce sites like Amazon for example, anything from basic HTML pages to complex systems. Web apps are developed with various programming languages and frameworks to create dynamic content, and interactivity and they frequently connect with databases to store data and retrieve it when needed. Online shopping, social networking, banking and more on different platforms are made easy by them. With seamless user experiences in mind that shape the digital landscape of today’s world, these come equipped with responsive design and server-side processing.

RESTful API Development

Web development of modern times has RESTful API development as an integral part hence the need to provide a consistent way to build web services that can communicate through the internet. REST stands for Representational State Transfer and it is an architectural style that focuses on stateless client-server communication, uniform interfaces, and predefined operations that allow resources to be manipulated. The primary reasons why RESTful APIs are preferred in building distributed systems, mobile applications, and web services are their scalability, client-friendliness as well as flexibility.

package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)
func main() {
	r := gin.Default()
	r.GET("/hello", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"message": "Hello, World!"})
	})
	r.Run(":8080")
}

URL Shortener

A web service that shortens URLs and converts them into manageable links is called URL shortener. Shortened URLs refer users to the original, longer ones upon clicking on them. They are frequently used in social media, where there is a character limit to allow long URLs to be shared more easily. Generally, URL shorteners have a unique identifier or code that they use as a stand-in for the full text of the URL during storage and retrieval. These are vital tools in marketing strategies, affiliate links and sorting complicated URLs because they provide an easy way to share URLs and tracking click statistics.

package main
import (
	"net/http"
	"math/rand"
	"time"
	"github.com/gin-gonic/gin"
)

var urlMap = make(map[string]string)
func main() {
	rand.Seed(time.Now().UnixNano())
	r := gin.Default()
	r.POST("/shorten", shortenURL)
	r.GET("/:shortURL", redirectURL)
	r.Run(":8080")
}

func shortenURL(c *gin.Context) {
	longURL := c.PostForm("url")
	shortURL := generateShortURL()
	urlMap[shortURL] = longURL
	c.JSON(http.StatusOK, gin.H{"shortURL": shortURL})
}

func redirectURL(c *gin.Context) {
	shortURL := c.Param("shortURL")
	longURL, ok := urlMap[shortURL]
	if !ok {
		c.JSON(http.StatusNotFound, gin.H{"message": "Short URL not found"})
		return
	}
	c.Redirect(http.StatusMovedPermanently, longURL)
}

func generateShortURL() string {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	shortURL := make([]byte, 6)
	for i := range shortURL {
		shortURL[i] = charset[rand.Intn(len(charset))]
	}
	return string(shortURL)
}

In this example:

  • POST /shorten: Accepts a long URL and generates a short URL for it.
  • GET /:shortURL: Redirects to the corresponding long URL when accessed with a short URL.

This code generates a random 6-character string to represent the short URL. The short URLs and their corresponding long URLs are stored in a map for simplicity.

Command-Line Interface (CLI) Tools

mac cli

There is software called Command-Line Interface (CLI) tools that are purposely created to be run through a text-based interface, enabling individuals to connect with their computers or programs without making use of any graphics. Commands typed in by users on the terminal prompt or in a command line may be accepted, and CLI tools can execute various tasks from basic file manipulation to complicated system administration tasks. CLI tools thus assist power users and developers have total control over system resources, automating things fast and running them without using graphical user interfaces. CLI tools are commonly found in computer systems due to their efficiency, adaptability as well as seamless integration into scripting and automation workflows.

File System Utility

The creation of a File System Utility CLI tool in Golang entails the use of standard library’s os and path/filepath packages to carry out such tasks as listing files, creating directories, and moving files among others. The example below is for a very basic File System Utility CLI tool in Golang;


package main
import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
)
func main() {
	fmt.Println("Welcome to File System Utility CLI Tool!")
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print("\nEnter command (ls, mkdir, mv, exit): ")
		command, _ := reader.ReadString('\n')
		command = trimNewline(command)
		switch command {
		case "ls":
			listFiles()
		case "mkdir":
			makeDirectory(reader)
		case "mv":
			moveFile(reader)
		case "exit":
			fmt.Println("Exiting...")
			return
		default:
			fmt.Println("Invalid command. Please try again.")
		}
	}
}

func listFiles() {
	files, err := filepath.Glob("*")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("Files in the current directory:")
	for _, file := range files {
		fmt.Println("-", file)
	}
}

func makeDirectory(reader *bufio.Reader) {
	fmt.Print("Enter directory name: ")
	dirName, _ := reader.ReadString('\n')
	dirName = trimNewline(dirName)
	err := os.Mkdir(dirName, 0755)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("Directory created successfully:", dirName)
}

func moveFile(reader *bufio.Reader) {
	fmt.Print("Enter source file name: ")
	srcFileName, _ := reader.ReadString('\n')
	srcFileName = trimNewline(srcFileName)
	fmt.Print("Enter destination directory: ")
	destDir, _ := reader.ReadString('\n')
	destDir = trimNewline(destDir)

	err := os.Rename(srcFileName, filepath.Join(destDir, srcFileName))
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("File moved successfully.")
}

func trimNewline(s string) string {
	return s[:len(s)-1]
}

This CLI tool provides basic functionalities such as listing files in the current directory (ls command), creating a directory (mkdir command), and moving a file to another directory (mv command). Users can input commands interactively via the terminal.

Text Processing Tool

Designing a CLI tool based on Golang to handle text involves using functions that change string values including those relating to regular expressions related to difficult works.


package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
	fmt.Println("Welcome to Text Processing CLI Tool!")
	reader := bufio.NewReader(os.Stdin)

	for {
		fmt.Print("\nEnter command (count, reverse, uppercase, lowercase, exit):")
		command, _ := reader.ReadString('\n')
		command = trimNewline(command)

		switch command {
		case "count":
			countWords(reader)
		case "reverse":
			reverseText(reader)
		case "uppercase":
			convertCase(reader, strings.ToUpper)
		case "lowercase":
			convertCase(reader, strings.ToLower)
		case "exit":
			fmt.Println("Exiting...")
			return
		default:
			fmt.Println("Invalid command. Please try again.")
		}
	}
}

func countWords(reader *bufio.Reader) {
	fmt.Print("Enter text: ")
	text, _ := reader.ReadString('\n')
	text = trimNewline(text)

	words := strings.Fields(text)
	fmt.Println("Number of words:", len(words))
}

func reverseText(reader *bufio.Reader) {
	fmt.Print("Enter text: ")
	text, _ := reader.ReadString('\n')
	text = trimNewline(text)

	reversed := reverseString(text)
	fmt.Println("Reversed text:", reversed)
}

func convertCase(reader *bufio.Reader, convertFunc func(string) string) {
	fmt.Print("Enter text: ")
	text, _ := reader.ReadString('\n')
	text = trimNewline(text)

	converted := convertFunc(text)
	fmt.Println("Converted text:", converted)
}

func trimNewline(s string) string {
	return strings.TrimSuffix(s, "\n")
}

func reverseString(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

Data-Driven Applications

data driven

Data-driven applications are software programs that utilize data as a primary asset to inform decision-making, improve user experiences, and drive business outcomes. These applications collect, process, analyze, and present data to users or other systems in meaningful ways. By leveraging data from various sources such as databases, APIs, sensors, or user interactions, data-driven applications enable organizations to gain insights, optimize processes, and deliver personalized services. They often employ techniques such as data visualization, machine learning, and predictive analytics to extract valuable insights and drive informed actions, empowering businesses to make data-driven decisions and stay competitive in today’s digital landscape.

Real-Time Data Stream Processing

To start, real-time data stream processing is the method of handling continuous streams of data as they are generated, offering immediate analysis, processing and response. You can use various libraries and frameworks such as Gorilla WebSocket for web socket connections, Go channels for concurrency and Kafka or NATS for message brokering to implement real-time data stream processing in Go. Below is a basic example that demonstrates how to build a simple application using Go:


package main

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

	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{}

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println("Error upgrading to WebSocket:", err)
		return
	}
	defer conn.Close()

	for {
		// Simulate real-time data stream
		message := "New data: " + time.Now().Format(time.RFC3339)
		if err := conn.WriteMessage(websocket.TextMessage, []byte(message)); err != nil {
			log.Println("Error writing message to WebSocket:", err)
			return
		}
		time.Sleep(1 * time.Second) // Simulate data stream frequency
	}
}

func main() {
	http.HandleFunc("/ws", handleWebSocket)

	fmt.Println("Starting server on port 8080...")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("Error starting server:", err)
	}
}

In this Example:

  1. An HTTP server was installed that listens for WebSocket connections via /ws.
  2. Once a connection is established, the server will always send real-time data to the client every second.
  3. Upon arrival of the real-time data, it can be handled and processed by the client.

This is a simple example illustrating how to do real-time data stream processing in Go. In practice, you would integrate this with actual sources of data, processing logic and possibly a message broker for scalability and reliability.

Data Analysis and Visualisation Tool

To develop data analysis and visualisation tools in Go, developers can use libraries for manipulating, analysing and visualising data. Popularly used for data manipulation in Go is the package gonum.org/v1/gonum which has various mathematical functions and data structures. To create plots and charts, it is powerful to use github.com/gonum/plot as a library for visualisation. Let me show you a simple example of writing a data analysis and visualisation tool in Go:


package main

import (
	"fmt"
	"log"
	"math/rand"
	"os"

	"gonum.org/v1/gonum/stat"
	"gonum.org/v1/plot"
	"gonum.org/v1/plot/plotter"
	"gonum.org/v1/plot/vg"
)

func main() {
	// Generate sample data
	data := make([]float64, 100)
	for i := range data {
		data[i] = rand.NormFloat64()
	}

	// Calculate mean and standard deviation
	mean := stat.Mean(data, nil)
	stdDev := stat.StdDev(data, nil)

	fmt.Printf("Mean: %.2f\n", mean)
	fmt.Printf("Standard Deviation: %.2f\n", stdDev)

	// Create histogram
	hist := plotter.Values(data)
	p, err := plot.New()
	if err != nil {
		log.Fatal(err)
	}
	p.Title.Text = "Histogram"
	p.X.Label.Text = "Value"
	p.Y.Label.Text = "Frequency"
	histogram, err := plotter.NewHist(hist, 16)
	if err != nil {
		log.Fatal(err)
	}
	p.Add(histogram)

	// Save histogram to a file
	if err := p.Save(8*vg.Inch, 4*vg.Inch, "histogram.png"); err != nil {
		log.Fatal(err)
	}
	fmt.Println("Histogram saved as histogram.png")
}

In this example:

  1. For instance, we create random sample data through the application of rand.NormFloat64() function.

  2. By employing functions from the gonum.org/v1/gonum/stat package, the mean and standard deviation of the data are calculated.

  3. Data histogram is created by using the gonum.org/v1/plot package.

  4. Save histogram as image file (histogram.png).

This is a simple example to illustrate how to analyse and present data in the Go programming language. Please feel free to expand on this example according to your specific requirements in terms of more advanced analysis techniques and different types of visualisations that you may be interested in developing.

Exploring DevOps

devops

Integration of software development (Dev) and IT operations (Ops) characterise exploration into DevOps and this is aimed at making the entire software delivery cycle simpler. It highlights automating processes, strengthening teamwork as well as fostering greater efficiency which helps in speeding up the development process and its deployment. Other DevOps practices encompass monitoring, infrastructure as code, continuous delivery and continuous integration among many others. The elimination of barriers between developers and system programmers quickens release cycles, enhances the reliability of produced software products, and makes it much easier for IT organisations to meet customer needs. This way of thinking promotes an innovative collaboration culture that fuels improvement for a high-speed business environment in the current digital era.

CI/CD Pipeline for Golang

Incorporating a CI/CD pipeline with Go involves automatic build, test and deployment processes. Various tools like Jenkins, GitLab CI/CD or GitHub Actions can however be used to coordinate the pipeline. Here is an example of a basic CI/CD pipeline that employs GitHub Actions to build and test Go application:

name: Go CI/CD Pipeline

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
      
    - name: Set up Go
      uses: actions/setup-go@v2
      with:
        go-version: 1.17

    - name: Build
      run: go build -v ./...

    - name: Test
      run: go test -v ./...

  deploy:
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'

    steps:
    - name: Deploy to server
      run: |
        # Add deployment script here        

Just to take an example:

  1. Whenever a push is made to the main branch, the pipeline will be triggered.

  2. The build job involves checking out the repository, setting up Go, building the application and running tests.

  3. The deploy job depends on the build job and if it’s a push to the main branch, applies deployment for the application.

Configuration Management Too

To customise this pipeline, you need to add steps that enable deployment of your server or cloud platform. In addition, it can be integrated with other tools like Docker for containerisation or Kubernetes for orchestration to create an end-to-end CI/CD pipeline for your Go application.


package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
)

// Config represents the configuration settings
type Config struct {
	Database struct {
		Host     string `json:"host"`
		Port     int    `json:"port"`
		Username string `json:"username"`
		Password string `json:"password"`
	} `json:"database"`
	Server struct {
		Port int `json:"port"`
	} `json:"server"`
}

func main() {
	// Load configuration from file
	config, err := loadConfig("config.json")
	if err != nil {
		log.Fatal("Error loading configuration:", err)
	}

	// Print configuration settings
	fmt.Println("Database Configuration:")
	fmt.Println("Host:", config.Database.Host)
	fmt.Println("Port:", config.Database.Port)
	fmt.Println("Username:", config.Database.Username)
	fmt.Println("Password:", config.Database.Password)

	fmt.Println("\nServer Configuration:")
	fmt.Println("Port:", config.Server.Port)
}

func loadConfig(filename string) (*Config, error) {
	// Read configuration file
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}

	// Unmarshal JSON data into Config struct
	var config Config
	if err := json.Unmarshal(data, &config); err != nil {
		return nil, err
	}

	return &config, nil
}
  1. This instance will define a configuration struct to hold all the information needed including database and server configurations.

  2. In addition, the loadConfig function reads configurations from a JSON file and unmarshals them in the Config structure.

  3. After loading the configuration from the config.json file, the main prints out some of it which includes those of database and server.

In addition to all these, you can make it possible for this tool to support other different configuration formats like YAML or TOML or have it read configurations from environment variables; also configurable settings may be loaded from a remote service. Additionally, error handling should be in place as well as checks that will help validate data entry on configurations

Building a Chat Application with WebSockets

chat

When building a chat application with WebSockets in Go, it is necessary to create a server that handles WebSocket connections and a client that connects and sends/receives messages. One simple example that demonstrates a basic chat application is as follows:

chat_server.go


package main

import (
	"log"
	"net/http"

	"github.com/gorilla/websocket"
)

var (
	upgrader = websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
)

func main() {
	http.HandleFunc("/ws", handleWebSocket)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println("Error upgrading to WebSocket:", err)
		return
	}
	defer conn.Close()

	for {
		messageType, msg, err := conn.ReadMessage()
		if err != nil {
			log.Println("Error reading message:", err)
			break
		}

		if err := conn.WriteMessage(messageType, msg); err != nil {
			log.Println("Error writing message:", err)
			break
		}
	}
}

chat_client.go


package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/gorilla/websocket"
)

func main() {
	conn, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/ws", nil)
	if err != nil {
		log.Fatal("Error connecting to WebSocket:", err)
	}
	defer conn.Close()

	go func() {
		for {
			_, msg, err := conn.ReadMessage()
			if err != nil {
				log.Println("Error reading message:", err)
				return
			}
			fmt.Println("Received:", string(msg))
		}
	}()

	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print("Enter message: ")
		message, _ := reader.ReadString('\n')
		message = message[:len(message)-1]

		err := conn.WriteMessage(websocket.TextMessage, []byte(message))
		if err != nil {
			log.Println("Error writing message:", err)
			return
		}
		time.Sleep(time.Second) // Delay to allow reading messages
	}
}

To run the example above:

  1. Save the server code named chat_server.go and the client code named chat_client.go.

  2. Open two terminal windows then navigate to where you have saved the files.

  3. In one terminal, type go run chat_server.go to start the server.

  4. In the other terminal, type go run chat_client.go to start your client.

  5. On the client terminal just enter messages and send them over to the server which will in turn echo them back.

One example of a simple chatting program whereby all messages received from clients are echoed back by a server is shown here. If necessary, this can be expanded to support multiple clients, user authentication, message broadcasting or any other advanced features that you may need.

Image Processing and Computer Vision with Golang

eye

GoCV is an alternative Go’s library that can be used to perform tasks related to image processing and computer vision, this by giving Go bindings for OpenCV, the famous computer vision library. The following is a demonstration of basic image processing using GoCV:


package main

import (
	"gocv.io/x/gocv"
)

func main() {
	// Read an image from file
	img := gocv.IMRead("input.jpg", gocv.IMReadColor)
	if img.Empty() {
		panic("Error reading image")
	}
	defer img.Close()

	// Convert the image to grayscale
	gray := gocv.NewMat()
	defer gray.Close()
	gocv.CvtColor(img, &gray, gocv.ColorBGRToGray)

	// Display the original and grayscale images
	window := gocv.NewWindow("Original")
	defer window.Close()
	window.IMShow(img)

	grayWindow := gocv.NewWindow("Grayscale")
	defer grayWindow.Close()
	grayWindow.IMShow(gray)

	// Wait for a key press to close the windows
	gocv.WaitKey(0)
}

In the example above we have:

  1. Used GoCV to load an image from a file (input.jpg) and convert it to grayscale.

  2. Displayed the original and grayscale images in separate windows.

  3. The program waits for a key press to close the windows.

To run this example, GoCV should be installed on your system and OpenCV should be installed as its dependency first. Then, save this code into a file (e.g., image_processing.go) and execute it using go run command.

This is just a basic introduction to Go programming language for image processing. You can also try advanced properties of GoCV and OpenCV such as object detection, face recognition or image segmentation in order to solve the mentioned tasks as well

Note

Thank you for taking the time to read this article. If you found it helpful, please consider sharing it with others and bookmarking this site for future reference.


Tags