GO API Server With GIN


8 min read

Getting Started with GoLang API Using Gin + Scalable Project Structure

Go is a great language for building fast, reliable, and efficient APIs. Pair it with the Gin framework and you get minimal boilerplate and high performance. This tutorial walks you through setting up a basic Gin API and organizing it with a modular structure suitable for real-world applications.

Prerequisites
Step 1: Initialize Your Project
mkdir go-gin-api && cd go-gin-api
go mod init github.com/yourusername/go-gin-api
Step 2: Install Gin
go get -u github.com/gin-gonic/gin
Step 3: Basic API Example

Create a simple main.go:

package main

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

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

    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{"message": "pong"})
    })

    r.Run(":8080") // listen and serve on localhost:8080
}

Run it:

go run main.go
Step 4: Scalable Modular Folder Structure

Here’s a recommended structure:

go-gin-api/
├── cmd/                # Entry point (main app)
   └── server/         # server logic (main.go)
       └── main.go
├── internal/           # Private application code
   ├── config/         # App configs (env, init)
   └── config.go
   ├── routes/         # Route registration
   └── router.go
   ├── handler/        # HTTP handlers
   └── user.go
   ├── service/        # Business logic
   └── user_service.go
   ├── model/          # Data models
   └── user.go
   └── repository/     # Data persistence logic
       └── user_repo.go
├── pkg/                # Shared utilities (JWT, logger, etc.)
   └── logger/
       └── logger.go
├── go.mod
└── go.sum
File Breakdown

cmd/server/main.go

package main

import (
    "github.com/yourusername/go-gin-api/internal/config"
    "github.com/yourusername/go-gin-api/internal/routes"
    "github.com/gin-gonic/gin"
)

func main() {
    config.LoadEnv()
    r := gin.Default()
    routes.RegisterRoutes(r)
    r.Run(":8080")
}

internal/config/config.go

package config

import (
    "github.com/joho/godotenv"
    "log"
)

func LoadEnv() {
    err := godotenv.Load()
    if err != nil {
        log.Println("No .env file found. Using system environment variables.")
    }
}

internal/routes/router.go

package routes

import (
    "github.com/gin-gonic/gin"
    "github.com/yourusername/go-gin-api/internal/handler"
)

func RegisterRoutes(r *gin.Engine) {
    api := r.Group("/api")
    {
        api.GET("/users/:id", handler.GetUser)
    }
}

internal/handler/user.go

package handler

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

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

internal/service/user_service.go

package service

func GetUserByID(id string) string {
    return "User_" + id
}

internal/model/user.go

package model

type User struct {
    ID   string `json:"id"`
    Name string `json:"name"`
}

internal/repository/user_repo.go

package repository

import "github.com/yourusername/go-gin-api/internal/model"

func FindUserByID(id string) model.User {
    return model.User{
        ID:   id,
        Name: "Mock User",
    }
}
Next Steps:
Conclusion

You’ve just built a basic but clean and modular Go API using Gin. This structure keeps handlers, services, and data layers separate — perfect for scaling and maintaining clean code.

Key Words:

GoGoLangAPI GIN