Gin

Gin is a fast, minimalist web framework written in Go. It's ideal for building APIs and web services with a strong focus on performance and productivity.

Project Structure

gin-project/
├── cmd/
│   └── main.go
├── config/
│   └── config.go
├── controllers/
│   └── user_controller.go
├── routes/
│   └── router.go
├── middleware/
│   └── logger.go
├── models/
│   └── user.go
├── services/
│   └── user_service.go
├── test/
│   └── user_test.go
├── go.mod
├── go.sum
├── .env

cmd/main.go

Entry point of the application.

package main

import (
    "gin-project/config"
    "gin-project/routes"
    "github.com/joho/godotenv"
    "log"
)

func main() {
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }

    config.ConnectDatabase()
    r := routes.SetupRouter()
    r.Run(":8080")
}

routes/router.go

Route registration file.

package routes

import (
    "gin-project/controllers"
    "gin-project/middleware"
    "github.com/gin-gonic/gin"
)

func SetupRouter() *gin.Engine {
    r := gin.Default()
    r.Use(middleware.Logger())

    user := r.Group("/user")
    {
        user.GET("/", controllers.GetUsers)
        user.GET("/:id", controllers.GetUserByID)
        user.POST("/", controllers.CreateUser)
    }

    return r
}

controllers/user_controller.go

User handler functions.

package controllers

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

func GetUsers(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{"message": "All users"})
}

func GetUserByID(c *gin.Context) {
    id := c.Param("id")
    c.JSON(http.StatusOK, gin.H{"id": id})
}

func CreateUser(c *gin.Context) {
    c.JSON(http.StatusCreated, gin.H{"message": "User created"})
}

middleware/logger.go

Simple request logger.

package middleware

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

func Logger() gin.HandlerFunc {
    return func(c *gin.Context) {
        t := time.Now()
        c.Next()
        latency := time.Since(t)
        log.Printf("[%s] %s - %v", c.Request.Method, c.Request.URL.Path, latency)
    }
}

models/user.go

User model definition.

package models

type User struct {
    ID    uint   `json:"id" gorm:"primaryKey"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

config/config.go

Database connection setup.

package config

import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
    "log"
)

var DB *gorm.DB

func ConnectDatabase() {
    database, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        log.Fatal("Failed to connect to database!")
    }
    DB = database
}

test/user_test.go

Basic test with Go’s testing package.

package test

import (
    "testing"
)

func TestSum(t *testing.T) {
    sum := 2 + 2
    if sum != 4 {
        t.Errorf("Expected 4 but got %d", sum)
    }
}

Running the Project

go run cmd/main.go

Running Tests

go test ./...

Environment Variables

Use .env to store secret values like database credentials and API keys.