Panduan lengkap untuk membangun API yang aman dan teroptimasi menggunakan Gin Framework dan GORM. Mencakup contoh kode siap produksi untuk autentikasi, integrasi database, dan pengujian dengan praktik terbaik untuk aplikasi Go yang dapat dipelihara.
Performa tinggi, sintaks sederhana, dan dukungan concurrency bawaan membuat Go ideal untuk layanan backend modern.
Kombinasi Gin framework, GORM ORM, dan tools testing untuk pengembangan API yang efisien dan maintainable.
Membangun REST API dengan autentikasi, otorisasi, dan integrasi database yang aman serta terstruktur.
Gin memberikan performa 40x lebih cepat dibanding net/http standar dengan overhead minimal dan routing yang efisien.
Routing sederhana, dukungan middleware, validasi JSON otomatis, dan binding request yang mudah digunakan.
Instalasi dengan perintah: go get -u github.com/gin-gonic/gin dan siap digunakan langsung.
Gin menawarkan keseimbangan sempurna antara performa dan kemudahan penggunaan.
Meski Fiber lebih cepat, Gin lebih stabil untuk produksi.
Organisasi kode yang baik memudahkan maintenance dan scaling.
Membuat routes untuk GET, POST, PUT, DELETE dengan handler yang sesuai untuk setiap endpoint.
Mengelola path parameters, query strings, dan request body dengan binding otomatis ke struct.
Strukturisasi data response dengan format JSON yang konsisten dan error handling yang proper.
Organisasi file untuk maintainability dengan separation of concerns yang jelas antara controllers, services, dan repositories.
Inisialisasi go module dan pengelolaan dependencies menggunakan go.mod untuk reproducible builds.
Setup environment variables dan configuration management untuk berbagai environment (dev, staging, production).
Semua kode dalam satu file main.go. Cocok untuk prototyping dan aplikasi kecil.
Pemisahan controller, model, dan view. Ideal untuk aplikasi medium dengan tim kecil.
Arsitektur berlapis dengan dependency injection. Recommended untuk aplikasi enterprise dan tim besar.
Setup HTTP server dasar dengan Gin engine dan konfigurasi port untuk development.
Mendefinisikan routes dan handler functions untuk endpoint RESTful dengan method yang sesuai.
Implementasi request-response cycle dengan parsing input dan formatting output yang konsisten.
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
r.Run(":8080")
}
Kode dasar untuk menginisialisasi server Gin dengan endpoint sederhana. Server akan berjalan di port 8080 dan merespons GET request ke /ping dengan JSON response.
Mengambil data dengan parameter URL dan query strings untuk filtering dan pagination yang efisien.
Mengirim dan mengupdate data dengan request body validation dan proper status code responses.
Menghapus resources dengan konfirmasi dan soft delete untuk data integrity yang terjaga.
Implementasi lengkap API dengan method GET dan POST. Termasuk struktur data dan validation basic.
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
type User struct {
ID int `json:"id"`
Name string `json:"name" binding:"required"`
Email string `json:"email" binding:"required,email"`
}
var users []User
var nextID = 1
func main() {
r := gin.Default()
// GET all users
r.GET("/users", getUsers)
// POST new user
r.POST("/users", createUser)
r.Run(":8080")
}
func getUsers(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"data": users,
"count": len(users),
})
}
func createUser(c *gin.Context) {
var newUser User
if err := c.ShouldBindJSON(&newUser); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
newUser.ID = nextID
nextID++
users = append(users, newUser)
c.JSON(http.StatusCreated, gin.H{
"message": "User created successfully",
"data": newUser,
})
}Code mendemonstrasikan CRUD operations dasar dengan validation dan proper HTTP status codes.
Middleware memproses request sebelum mencapai handler utama.
Logger, Recovery, dan CORS middleware tersedia out-of-the-box.
Membuat middleware khusus untuk autentikasi dan validasi bisnis logic.
Menggabungkan multiple middleware dengan urutan eksekusi yang tepat.
Binding otomatis JSON request ke Go structs dengan tag validation untuk memastikan data integrity dan type safety.
Teknik validasi input yang komprehensif termasuk format checking, range validation, dan business rule enforcement.
Validasi request memastikan data yang masuk sesuai format yang diharapkan. Gin menyediakan binding otomatis untuk JSON dengan tag validation.
Struct tags seperti required, email, dan min memberikan validasi built-in. Error handling yang proper mencegah data corrupt masuk ke sistem.
type RegisterRequest struct {
Username string `json:"username" binding:"required,min=3,max=20"`
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=8"`
Age int `json:"age" binding:"required,min=18,max=100"`
}
func registerUser(c *gin.Context) {
var req RegisterRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid input",
"details": err.Error(),
})
return
}
// Process valid data
c.JSON(http.StatusOK, gin.H{
"message": "User registered successfully",
"username": req.Username,
})
}
Implementasi lengkap JSON binding dengan validasi input menggunakan struct tags. Kombinasi binding dan validate tags memastikan data integrity.
Error handling yang comprehensive mencakup validation errors dan JSON parsing errors. Response yang informatif membantu debugging client-side integration.
type User struct {
Username string `json:"username" binding:"required,min=3,max=20"`
Email string `json:"email" binding:"required,email"`
Age int `json:"age" binding:"required,gte=18,lte=100"`
Password string `json:"password" binding:"required,min=8"`
}
func createUser(c *gin.Context) {
var user User
if err := c.ShouldBindJSON(&user); err != nil {
var validationErrors []string
if ve, ok := err.(validator.ValidationErrors); ok {
for _, e := range ve {
switch e.Tag() {
case "required":
validationErrors = append(validationErrors,
fmt.Sprintf("%s is required", e.Field()))
case "email":
validationErrors = append(validationErrors,
"Invalid email format")
case "min":
validationErrors = append(validationErrors,
fmt.Sprintf("%s must be at least %s characters",
e.Field(), e.Param()))
}
}
}
c.JSON(http.StatusBadRequest, gin.H{
"status": "error",
"message": "Validation failed",
"errors": validationErrors,
})
return
}
c.JSON(http.StatusCreated, gin.H{
"status": "success",
"message": "User created successfully",
"data": user,
})
}Format response konsisten
Standardisasi error messages
Pagination dan filtering
Response formatting yang konsisten memudahkan client integration dan debugging. Struktur yang jelas dengan error codes yang meaningful membantu developer memahami API behavior.
Implementasi lengkap response formatting yang konsisten dengan error handling dan data management terintegrasi.
package main
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
type APIResponse struct {
Status string `json:"status"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
Errors []string `json:"errors,omitempty"`
Meta *Meta `json:"meta,omitempty"`
Version string `json:"version"`
}
type Meta struct {
Page int `json:"page"`
Limit int `json:"limit"`
Total int `json:"total"`
TotalPages int `json:"total_pages"`
}
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
var users = []User{
{ID: 1, Name: "John Doe", Email: "john@example.com"},
{ID: 2, Name: "Jane Smith", Email: "jane@example.com"},
}
func successResponse(c *gin.Context, message string, data interface{}, meta *Meta) {
response := APIResponse{
Status: "success",
Message: message,
Data: data,
Meta: meta,
Version: "v1",
}
c.JSON(http.StatusOK, response)
}
func errorResponse(c *gin.Context, statusCode int, message string, errors []string) {
response := APIResponse{
Status: "error",
Message: message,
Errors: errors,
Version: "v1",
}
c.JSON(statusCode, response)
}
func getUsers(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
if page < 1 {
page = 1
}
if limit < 1 || limit > 100 {
limit = 10
}
start := (page - 1) * limit
end := start + limit
if start >= len(users) {
successResponse(c, "Users retrieved successfully", []User{}, &Meta{
Page: page,
Limit: limit,
Total: len(users),
TotalPages: (len(users) + limit - 1) / limit,
})
return
}
if end > len(users) {
end = len(users)
}
paginatedUsers := users[start:end]
meta := &Meta{
Page: page,
Limit: limit,
Total: len(users),
TotalPages: (len(users) + limit - 1) / limit,
}
successResponse(c, "Users retrieved successfully", paginatedUsers, meta)
}
func getUserByID(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
errorResponse(c, http.StatusBadRequest, "Invalid user ID", []string{"ID must be a valid number"})
return
}
for _, user := range users {
if user.ID == id {
successResponse(c, "User found", user, nil)
return
}
}
errorResponse(c, http.StatusNotFound, "User not found", []string{"User with specified ID does not exist"})
}
func main() {
r := gin.Default()
// API versioning
v1 := r.Group("/api/v1")
{
v1.GET("/users", getUsers)
v1.GET("/users/:id", getUserByID)
}
r.Run(":8080")
}Broken Object Level Authorization, Broken User Authentication, Excessive Data Exposure, dan vulnerability lainnya yang umum pada API modern.
SQL injection, XSS, CSRF, dan security issues spesifik Go seperti race conditions dan memory leaks yang perlu diwaspadai.
Implementasi security headers, CORS policy, dan rate limiting untuk melindungi API dari berbagai jenis serangan.
JWT dan bearer tokens untuk stateless authentication
Server-side sessions dengan secure cookie handling
Third-party authentication dengan Google, GitHub, Facebook
Pemilihan metode autentikasi tergantung pada use case. Token-based authentication cocok untuk mobile apps dan SPA, sementara session-based lebih sesuai untuk traditional web applications.
func BasicAuth() gin.HandlerFunc {
return gin.BasicAuth(gin.Accounts{
"admin": "secret123",
"user": "password",
})
}
func setupRoutes() *gin.Engine {
r := gin.Default()
authorized := r.Group("/admin", BasicAuth())
authorized.GET("/dashboard", getDashboard)
return r
}
Basic Authentication sederhana namun kurang aman untuk production. Gunakan HTTPS dan pertimbangkan untuk development environment saja karena credentials dikirim dalam setiap request.
Algorithm dan token type
Claims dan user data
Verification dengan secret key
Token renewal mechanism
Berisi algoritma enkripsi dan tipe token.
{
"alg": "HS256",
"typ": "JWT"
}Menyimpan claims dan data user.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622
}Verifikasi menggunakan secret key untuk keamanan.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)import "github.com/golang-jwt/jwt/v4"
func GenerateToken(userID uint) (string, error) {
claims := jwt.MapClaims{
"user_id": userID,
"exp": time.Now().Add(time.Hour * 24).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte("secret-key"))
}
func ValidateToken(tokenString string) (*jwt.Token, error) {
return jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte("secret-key"), nil
})
}
Implementasi JWT lengkap dengan token generation, validation, dan claims extraction. Pastikan menggunakan secret key yang kuat dan store secara aman di environment variables.
RBAC memungkinkan kontrol akses granular berdasarkan peran pengguna. Implementasi melibatkan middleware yang memeriksa role dan permissions sebelum mengizinkan akses ke endpoint tertentu.
RBAC mengatur akses berdasarkan peran pengguna. Setiap peran memiliki izin spesifik untuk resource tertentu.
Implementasi mencakup definisi roles, permissions, dan middleware untuk validasi akses secara otomatis.
package main
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v4"
)
type User struct {
ID uint `json:"id"`
Name string `json:"name"`
Role string `json:"role"`
}
type Claims struct {
UserID uint `json:"user_id"`
Role string `json:"role"`
jwt.RegisteredClaims
}
var users = map[uint]User{
1: {ID: 1, Name: "Admin", Role: "admin"},
2: {ID: 2, Name: "User", Role: "user"},
}
func RequireRole(allowedRoles ...string) gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.GetHeader("Authorization")
if tokenString == "" {
c.JSON(401, gin.H{"error": "Token required"})
c.Abort()
return
}
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
return []byte("secret-key"), nil
})
if err != nil || !token.Valid {
c.JSON(401, gin.H{"error": "Invalid token"})
c.Abort()
return
}
for _, role := range allowedRoles {
if claims.Role == role {
c.Set("user_id", claims.UserID)
c.Set("role", claims.Role)
c.Next()
return
}
}
c.JSON(403, gin.H{"error": "Insufficient permissions"})
c.Abort()
}
}
func main() {
r := gin.Default()
// Public endpoint
r.GET("/public", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Public access"})
})
// Admin only
r.GET("/admin", RequireRole("admin"), func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Admin area"})
})
// Admin and user
r.GET("/dashboard", RequireRole("admin", "user"), func(c *gin.Context) {
role := c.GetString("role")
c.JSON(200, gin.H{
"message": "Dashboard access",
"role": role,
})
})
r.Run(":8080")
}
Gunakan prepared statements dan parameterized queries dengan GORM untuk mencegah SQL injection attacks secara otomatis.
Sanitasi input dan escape output untuk mencegah Cross-Site Scripting dengan validation yang ketat.
Implementasi CSRF tokens dan SameSite cookies untuk melindungi dari Cross-Site Request Forgery.
Implementasi praktik coding yang aman mencegah berbagai jenis serangan. CSRF bekerja dengan memanfaatkan trust relationship antara browser dan server.
Attacker membuat request palsu yang terlihat legitimate dari user browser. Browser secara otomatis mengirim cookies dan credentials yang tersimpan.
Cara Kerja CSRF: User login ke aplikasi bank. Attacker kirim email dengan link berbahaya. Ketika diklik, browser kirim request transfer uang tanpa sepengetahuan user.
Pencegahan: Gunakan CSRF tokens yang unik setiap request. Validasi origin header dan implement SameSite cookie attributes untuk blocking cross-site requests.
Selalu sanitasi input data dan gunakan prepared statements. Implement rate limiting dan logging untuk monitoring suspicious activities secara real-time.
Tiga ancaman keamanan utama yang sering ditemukan dalam aplikasi web. SQL Injection memungkinkan penyerang memanipulasi database melalui input yang tidak tervalidasi.
Cross-Site Scripting (XSS) memungkinkan eksekusi script berbahaya di browser pengguna. Cross-Site Request Forgery (CSRF) memaksa pengguna melakukan aksi tidak diinginkan.
// SQL Injection Vulnerability
func getUserByID(id string) User {
query := "SELECT * FROM users WHERE id = " + id
// DANGEROUS: Direct string concatenation
rows, _ := db.Query(query)
// Attacker input: "1 OR 1=1"
}
// XSS Vulnerability
func displayComment(comment string) {
// DANGEROUS: Unescaped output
html := "<div>" + comment + "</div>"
// Attacker input: "<script>alert('XSS')</script>"
}
// CSRF Vulnerability
func deleteUser(c *gin.Context) {
// DANGEROUS: No CSRF protection
userID := c.Param("id")
db.Delete(&User{}, userID)
}Implementasi yang tepat menggunakan prepared statements, HTML escaping, dan CSRF tokens untuk melindungi aplikasi dari serangan ini.
Implementasi yang tepat menggunakan prepared statements, HTML escaping, dan CSRF tokens mencegah serangan keamanan umum.
GORM secara otomatis melindungi dari SQL injection. Middleware Gin menyediakan perlindungan XSS dan CSRF built-in.
// SQL Injection Prevention dengan GORM
func getUserByID(id uint) (User, error) {
var user User
// SAFE: GORM menggunakan prepared statements
result := db.First(&user, id)
return user, result.Error
}
// XSS Prevention dengan HTML Escaping
func displayComment(c *gin.Context) {
comment := c.PostForm("comment")
// SAFE: Gin secara otomatis escape HTML
c.HTML(200, "comment.html", gin.H{
"comment": comment, // Automatically escaped
})
}
// CSRF Prevention dengan Middleware
func setupCSRF() gin.HandlerFunc {
return csrf.Middleware(csrf.Options{
Secret: "your-secret-key",
ErrorFunc: func(c *gin.Context) {
c.JSON(403, gin.H{"error": "CSRF token invalid"})
},
})
}
func main() {
r := gin.Default()
r.Use(setupCSRF()) // Apply CSRF protection
r.POST("/delete/:id", deleteUser)
}GORM menyediakan abstraksi database yang powerful dengan mapping otomatis antara Go structs dan database tables.
Auto-migrations, associations, hooks, transactions, dan connection pooling untuk produktivitas maksimal.
Dukungan MySQL, PostgreSQL, SQLite, SQL Server dengan driver yang konsisten dan reliable.
GORM memetakan database tables secara otomatis ke Go structs. Field names dan types disesuaikan dengan konvensi Go.
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"size:100;not null"`
Email string `gorm:"uniqueIndex;not null"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
// Relationships
Posts []Post `gorm:"foreignKey:UserID"`
}
type Post struct {
ID uint `gorm:"primaryKey"`
Title string `gorm:"size:200;not null"`
UserID uint
User User `gorm:"references:ID"`
}
Model definition dengan struct tags untuk database constraints, relationships, dan indexing. Soft delete support dengan DeletedAt field untuk data recovery.
Establishing database connection dengan connection string dan driver yang sesuai untuk environment.
Setting connection pool, timeout, logging level, dan performance tuning parameters.
Otomatis membuat dan mengupdate database schema berdasarkan struct definitions.
import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func InitDB() (*gorm.DB, error) {
dsn := "host=localhost user=postgres password=secret dbname=myapp port=5432"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
})
if err != nil {
return nil, err
}
// Auto migrate
db.AutoMigrate(&User{}, &Product{})
return db, nil
}
Setup koneksi database dengan PostgreSQL driver, logging configuration, dan auto-migration untuk model User dan Product. Error handling memastikan aplikasi tidak crash saat database unavailable.
Insert single records, batch inserts, dan upsert operations dengan validation dan error handling yang proper.
Query dengan conditions, joins, preloading relationships, pagination, dan sorting untuk data retrieval yang efisien.
Update selective fields, batch updates, soft deletes, dan hard deletes dengan transaction support untuk data consistency.
type UserRepository struct {
db *gorm.DB
}
func (r *UserRepository) Create(user *User) error {
return r.db.Create(user).Error
}
func (r *UserRepository) GetByID(id uint) (*User, error) {
var user User
err := r.db.Preload("Posts").First(&user, id).Error
return &user, err
}
func (r *UserRepository) Update(user *User) error {
return r.db.Save(user).Error
}
func (r *UserRepository) Delete(id uint) error {
return r.db.Delete(&User{}, id).Error
}
Repository pattern implementation untuk encapsulation database operations. Preloading relationships dan proper error handling untuk robustness dan maintainability.
Membuat migration files dengan timestamp untuk version control dan reproducible schema changes.
Eksekusi migrations programmatically atau via CLI dengan tracking applied migrations.
Rollback mechanism untuk reverting schema changes ketika terjadi issues dalam production.
Peningkatan speed dengan preloading dan query optimization
Pengurangan memory footprint dengan selective loading
Reliability dengan proper error handling dan retries
Business logic dan entities
Use cases dan orchestration
Controllers dan presenters
Database dan external services
Handle HTTP requests, parameter binding, dan response formatting. Thin controllers yang delegate business logic ke service layer.
Business logic implementation dan data access layer. Services untuk use cases, models untuk data structure dan validation.
controllers/
├── user_controller.go
├── product_controller.go
└── auth_controller.goHTTP handlers untuk setiap endpoint API dengan request/response processing.
models/
├── user.go
├── product.go
└── database.goStruct definitions dan database schema dengan GORM annotations.
routes/
├── api.go
└── middleware.go
main.go
go.modRoute definitions, middleware setup, dan application entry point.
Clean Architecture membagi aplikasi menjadi lapisan-lapisan dengan batasan jelas untuk menciptakan sistem modular dan mudah diuji. Berbeda dengan MVC (3 komponen), Clean Architecture memiliki 4 lapisan terpisah dengan prinsip dependency inversion.
MVC memiliki batasan kurang tegas:
Clean Architecture terdiri dari:
Entities dan business rules core aplikasi (user entities, business logic, domain interfaces)
Application services dan orchestration logic (user services, repository interfaces, input/output ports)
Controllers, presenters, dan gateways (HTTP handlers, response formatters, request validators)
Database, external APIs, dan framework (GORM repositories, third-party APIs, configuration)
Alur request dari HTTP hingga database dengan pemisahan tanggung jawab yang jelas.
Client mengirim request ke API endpoint
Router menerima dan memproses HTTP request
Implementasi logika bisnis dan use cases
Interface untuk operasi data abstrak
Struktur data dan validasi business rules
Penyimpanan data persisten
Struktur proyek Clean Architecture memisahkan kode berdasarkan tanggung jawab. Setiap layer memiliki direktori yang jelas dan terorganisir.
cmd/server/main.go adalah entry point aplikasi. configs/ menyimpan konfigurasi sistem dan environment variables.
internal/handler/ berisi Gin HTTP handlers untuk komunikasi eksternal.
internal/service/ mengatur business logic dan use cases aplikasi.
internal/repository/ menangani database interaction dan persistence layer.
internal/domain/models/ menyimpan core entities tanpa dependency eksternal.
pkg/ berisi reusable libraries seperti JWT utilities dan logging functions yang dapat digunakan ulang.
Concurrency adalah composition of independent processes, parallelism adalah simultaneous execution pada multiple cores.
Goroutines memiliki overhead rendah (~2KB stack) dibanding OS threads, memungkinkan thousands concurrent operations.
Background processing, parallel database queries, async task execution, dan real-time notifications dalam API development.
Goroutines adalah lightweight threads yang memungkinkan concurrent execution dalam Go. Setiap goroutine hanya membutuhkan 2KB memory stack.
Keyword go digunakan untuk menjalankan function secara asynchronous. Runtime Go dapat mengelola ribuan goroutines secara efisien.
package main
import (
"fmt"
"time"
)
func sayHello(name string) {
for i := 0; i < 3; i++ {
fmt.Printf("Hello %s! %d\n", name, i)
time.Sleep(100 * time.Millisecond)
}
}
func main() {
// Sequential execution
sayHello("Alice")
// Concurrent execution with goroutines
go sayHello("Bob")
go sayHello("Charlie")
// Wait for goroutines to complete
time.Sleep(500 * time.Millisecond)
fmt.Println("Main function completed")
}Buffered dan unbuffered channels
Send, receive, dan close operations
Non-blocking channel operations dan timeouts
Channels adalah primary communication mechanism antara goroutines. "Don't communicate by sharing memory; share memory by communicating" adalah filosofi Go untuk safe concurrency.
Channel adalah komunikasi antar goroutines yang aman. Mereka memungkinkan pertukaran data tanpa race conditions.
Channel menggunakan operator <- untuk mengirim dan menerima data. Channel dapat buffered atau unbuffered sesuai kebutuhan.
// Membuat channel
ch := make(chan string)
// Mengirim data
go func() {
ch <- "Hello from goroutine"
}()
// Menerima data
message := <-ch
fmt.Println(message)
// Buffered channel
buffered := make(chan int, 3)
buffered <- 1
buffered <- 2Unbuffered channels menyinkronkan goroutines secara langsung. Setiap operasi send akan **memblokir** hingga ada receiver.
Channel ini ideal untuk **komunikasi real-time** antar goroutines dalam API processing. Tidak ada buffering data internal.
package main
import (
"fmt"
"time"
)
// Simulasi API request processing
func processAPIRequest(id int, ch chan string) {
// Simulate API processing time
time.Sleep(200 * time.Millisecond)
result := fmt.Sprintf("API Request %d processed", id)
ch <- result // Send ke channel (blocking)
}
func main() {
// Unbuffered channel
resultChan := make(chan string)
// Launch goroutines untuk process requests
for i := 1; i <= 3; i++ {
go processAPIRequest(i, resultChan)
}
// Receive results dari channel
for i := 1; i <= 3; i++ {
result := <-resultChan // Receive dari channel (blocking)
fmt.Println(result)
}
fmt.Println("All API requests completed")
}func ProcessOrdersConcurrently(orders []Order) error {
const maxWorkers = 10
orderChan := make(chan Order, len(orders))
errorChan := make(chan error, len(orders))
// Start workers
for i := 0; i < maxWorkers; i++ {
go func() {
for order := range orderChan {
if err := processOrder(order); err != nil {
errorChan <- err
} else {
errorChan <- nil
}
}
}()
}
// Send orders to channel
for _, order := range orders {
orderChan <- order
}
close(orderChan)
// Collect results
for i := 0; i < len(orders); i++ {
if err := <-errorChan; err != nil {
return err
}
}
return nil
}
Worker pool pattern untuk memproses multiple orders secara concurrent. Limiting jumlah workers mencegah resource exhaustion dan memberikan control yang lebih baik terhadap system load.
Kondisi dimana multiple goroutines mengakses shared memory secara bersamaan tanpa proper synchronization.
sync.Mutex menyediakan mutual exclusion untuk melindungi critical sections dari concurrent access.
sync.RWMutex memungkinkan multiple readers atau single writer untuk workload read-heavy.
type SafeCounter struct {
mu sync.Mutex
count int
}
func (c *SafeCounter) Increment() {
c.mu.Lock()
defer c.mu.Unlock()
c.count++
}
func (c *SafeCounter) Value() int {
c.mu.Lock()
defer c.mu.Unlock()
return c.count
}
// Usage in API handler
func incrementHandler(counter *SafeCounter) gin.HandlerFunc {
return func(c *gin.Context) {
counter.Increment()
c.JSON(200, gin.H{"count": counter.Value()})
}
}
Thread-safe counter implementation dengan mutex protection. Defer statement memastikan unlock selalu dipanggil meskipun terjadi panic, mencegah deadlock scenarios.
Go built-in testing package menyediakan framework lengkap untuk unit testing dengan simple API dan powerful features.
Pattern untuk testing multiple scenarios dengan data-driven approach, memudahkan maintenance dan coverage expansion.
Isolation unit under test dengan mocking external dependencies menggunakan interfaces dan dependency injection.
Go's httptest package menyediakan utilities untuk testing HTTP handlers tanpa starting actual server.
Testing Gin handlers dengan proper context setup dan middleware testing untuk comprehensive coverage.
func TestCreateUser(t *testing.T) {
gin.SetMode(gin.TestMode)
tests := []struct {
name string
payload string
expected int
}{
{"Valid user", `{"name":"John","email":"john@example.com"}`, 201},
{"Invalid email", `{"name":"John","email":"invalid"}`, 400},
{"Missing name", `{"email":"john@example.com"}`, 400},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := httptest.NewRecorder()
req, _ := http.NewRequest("POST", "/users", strings.NewReader(tt.payload))
req.Header.Set("Content-Type", "application/json")
router := setupRouter()
router.ServeHTTP(w, req)
assert.Equal(t, tt.expected, w.Code)
})
}
}
Table-driven test untuk API endpoint dengan multiple test scenarios. Comprehensive testing mencakup valid cases, validation errors, dan edge cases untuk robust API behavior.
Target throughput untuk API endpoints
Maximum acceptable latency
Minimum success rate under load
Maximum memory usage threshold
Domain-specific error types
Context preservation dengan wrapping
Consistent error response format
Comprehensive error logging dan monitoring
# Multi-stage Dockerfile for Go
FROM golang:1.19-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]
Multi-stage Docker build untuk optimized container size. Builder stage untuk compilation, final stage dengan minimal Alpine Linux untuk production deployment yang efficient.
Multiple instances dengan load balancing untuk handling increased traffic dan fault tolerance.
Session-less architecture dengan external state storage untuk seamless scaling dan deployment.
Database dan Redis connection pools untuk resource efficiency dan performance optimization.
Traffic distribution strategies dengan health checks dan graceful shutdown support.
Advanced Go API Development