
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
-
Go installed (1.19+ recommended): https://golang.org/dl/
-
Basic Go knowledge
-
go mod
initialized
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:
-
Add database (Postgres, MySQL, etc.) via
gorm
orsqlx
-
Add middleware (auth, logging)
-
Create tests (
*_test.go
) -
Add proper error handling (custom error wrappers)
-
Dockerize your app
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.
More Articles
Key Words:
GoGoLangAPI GIN