Tarkibga o'tish

Gin framework bilan tezkor API yaratish

Gin — Go uchun eng ko‘p ishlatiladigan web framework’lardan biri. U net/http ustiga qurilgan va API yozishda ko‘p uchraydigan vazifalar uchun tayyor yechimlar beradi: routing, marshrutlarni guruhlash, JSON o‘qish va yozish, validatsiya, logger va panicni ushlaydigan middleware’lar.

Oldingi bo‘limlarda bu ishlarning barchasini standart kutubxona bilan qo‘lda bajargan edik: writeJSON, decodeJSON, validator, xato formati, middleware zanjiri. Gin’da ularning ko‘pchiligi tayyor holda keladi. Shuning uchun endi Gin’ning har bir imkoniyati ortida nima turganini tushunib o‘rganamiz.

Gin nimalarni beradi?

Imkoniyat net/http bilan Gin bilan
Routing va parametrlar mux.HandleFunc("GET /books/{id}", h) r.GET("/books/:id", h)
Guruhlash Alohida mux va qo‘lda o‘rash r.Group("/api/v1")
JSON o‘qish va validatsiya decodeJSON + validator c.ShouldBindJSON(&req)
JSON javob writeJSON(w, 200, v) c.JSON(200, v)
Logger va recovery O‘zimiz yozdik gin.Default() ichida tayyor
Middleware ichida qiymat uzatish context.WithValue c.Set / c.Get

O‘rnatish

mkdir gin-books && cd gin-books
go mod init gin-books
go get github.com/gin-gonic/gin

Birinchi dastur

main.go
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.GET("/books/:id", func(c *gin.Context) {
        id := c.Param("id")
        lang := c.DefaultQuery("lang", "uz")
        c.JSON(http.StatusOK, gin.H{"id": id, "lang": lang})
    })

    r.Run(":8080")
}
go run main.go

Gin ishga tushganda debug rejimida marshrutlar ro‘yxatini chiqaradi:

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] GET    /books/:id                --> main.main.func2 (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8080

Ogohlantirishlarning ma’nosi:

  • debug rejimi ishlab chiqish uchun qulay, lekin production’da release rejimini yoqish kerak;
  • Gin standart holatda barcha proxy serverlarga ishonadi. Bu klient IP manzilini aniqlashga ta’sir qiladi.

Ikkala sozlama ham Performance darsida ko‘riladi.

curl http://localhost:8080/ping
curl "http://localhost:8080/books/42?lang=en"
{"message":"pong"}
{"id":"42","lang":"en"}

Server terminalida har bir so‘rov uchun log qatori chiqadi:

[GIN] 2026/09/30 - 10:00:00 | 200 |   52.193µs |       127.0.0.1 | GET      "/ping"

Kod qanday ishlaydi?

gin.Default() — ikkita middleware ulangan tayyor router yaratadi: Logger (har bir so‘rovni log qiladi) va Recovery (panicni ushlaydi). Marshrutlar ro‘yxatidagi (3 handlers) yozuvi ham shundan: 2 ta middleware va 1 ta handler.

r.GET(yo‘l, handler) — marshrut qo‘shadi. Har bir HTTP metodi uchun alohida funksiya bor: GET, POST, PUT, PATCH, DELETE.

:id — yo‘l parametri. Gin’da parametrlar {id} emas, :id ko‘rinishida yoziladi. U c.Param("id") bilan o‘qiladi.

*gin.Context — Gin handlerining yagona argumenti. U http.ResponseWriter va *http.Requestni o‘z ichiga oladi va ular ustida qulay metodlar beradi.

gin.H — map[string]any uchun qisqa nom. JSON javobni tez yozish uchun ishlatiladi.

c.DefaultQuery("lang", "uz") — query parametrni o‘qiydi, u bo‘lmasa standart qiymatni qaytaradi.

r.Run(":8080") — http.ListenAndServe(":8080", r) uchun qisqa yozuv.

Warning

r.Run ichida timeoutlarsiz http.Server yaratiladi. Production’da http.HandleFunc va http.ListenAndServe darsidagi kabi o‘z http.Serveringizni yarating va Handler sifatida Gin router’ini bering. Bu Performance darsida ko‘rsatiladi.

net/http bilan solishtirish

Bitta endpointni ikki usulda yozib ko‘ramiz:

net/http bilan:

func createBook(w http.ResponseWriter, r *http.Request) {
    var req CreateBookRequest
    if err := decodeJSON(w, r, &req); err != nil {
        writeError(w, http.StatusBadRequest, err.Error())
        return
    }
    if err := validate.Struct(req); err != nil {
        writeError(w, http.StatusUnprocessableEntity, err.Error())
        return
    }
    writeJSON(w, http.StatusCreated, req)
}

Gin bilan:

func createBook(c *gin.Context) {
    var req CreateBookRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    c.JSON(http.StatusCreated, req)
}

Gin variantida ShouldBindJSON JSON’ni o‘qish va validatsiyani birga bajaradi. Kod qisqa, lekin mantiq bir xil. return ham har ikkala variantda kerak.

Bo‘lim rejasi

Dars Mavzu
Gin arxitekturasi Engine, RouterGroup, Context, handlerlar zanjiri va radix tree
Request binding JSON, query va URI ma’lumotlarini struct’ga bog‘lash va validatsiya
JWT middleware Gin’da auth middleware yozish
Error handling Xatolarni markazlashgan holda qayta ishlash
Performance Release rejimi, server sozlamalari va tezlikni o‘lchash

Keyingi darsda Gin ichida nima bo‘layotganini tushunish uchun uning arxitekturasini ko‘rib chiqamiz.