GoDasturchi
Request Validation Basics

Request Validation Basics

So'rovlarni tekshirish (validatsiya) asoslari

Bank blankasini to'ldirganingizda, xodim uni QABUL QILISHDAN OLDIN tekshiradi: ism yozilganmi? summasi musbatmi? Agar biror maydon noto'g'ri bo'lsa, blanka SIZGA qaytariladi — bank tizimiga umuman KIRMAYDI. Request validation — API'da xuddi shu "xodim" vazifasini bajaradi: noto'g'ri ma'lumot BIZNES MANTIQQA (bazaga saqlash, hisoblash) YETMASDAN OLDIN rad etiladi.

example.go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"
)

type CreateBookRequest struct {
	Title  string  `json:"title"`
	Author string  `json:"author"`
	Price  float64 `json:"price"`
}

// validate — birinchi topilgan xatoni qaytaradi, hammasi to'g'ri bo'lsa "" qaytaradi
func validate(req CreateBookRequest) string {
	if strings.TrimSpace(req.Title) == "" {
		return "title bo'sh bo'lishi mumkin emas"
	}
	if strings.TrimSpace(req.Author) == "" {
		return "author bo'sh bo'lishi mumkin emas"
	}
	if req.Price <= 0 {
		return "price musbat son bo'lishi kerak"
	}
	return ""
}

func createHandler(w http.ResponseWriter, r *http.Request) {
	var req CreateBookRequest
	json.NewDecoder(r.Body).Decode(&req)

	if msg := validate(req); msg != "" {
		w.WriteHeader(http.StatusUnprocessableEntity)
		fmt.Fprint(w, msg)
		return
	}

	w.WriteHeader(http.StatusCreated)
	fmt.Fprint(w, "yaratildi")
}

func main() {
	req := httptest.NewRequest("POST", "/books", strings.NewReader(`{"title":"Go bilan tanishuv","price":45000}`))
	rec := httptest.NewRecorder()
	createHandler(rec, req)
	fmt.Println(rec.Code, rec.Body.String())
}

strings.TrimSpace(req.Title) == "" — nafaqat BO'SH matn (""), balki FAQAT bo'shliqlardan iborat matn (" ") ni ham "bo'sh" deb hisoblaydi — bu HAQIQIY validatsiyada juda TEZ-TEZ unutiladigan holat. req.Price <= 0 — narx NOL yoki MANFIY bo'lishi mumkin emasligini tekshiradi: bular "type-check" (JSON to'g'ri decode bo'ldimi) dan farqli, BIZNES QOIDA (business rule) validatsiyasi.

http.StatusUnprocessableEntity (422) — "HTTP Status Codes Done Right" darsida batafsil ko'radigan status: JSON STRUKTURASI to'g'ri (decode xatosiz o'tdi), lekin QIYMATLAR biznes qoidaga mos KELMAYDI. Bu — JSON umuman NOTO'G'RI formatlangan holatdagi 400 Bad Requestdan FARQLI holat.

>_ Exercise

Ombordagi son (Stock) uchun ham tekshiruv qo'shing.

  • CreateBookRequest'ga Stock int json:"stock" maydonini qo'shing
  • validate ichida: req.Stock < 0 bo'lsa "stock manfiy bo'lishi mumkin emas" qaytaring (Price tekshiruvidan KEYIN)
  • uchta holatni sinang: author yo'q, stock manfiy, va TO'LIQ to'g'ri so'rov — har birining natijasini chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Validatsiya — noto'g'ri ma'lumotni biznes mantiqqa yetmasdan oldin, ANIQ va TUSHUNARLI xato xabari bilan rad etadi; bo'sh matn va manfiy sonlar kabi "oddiy" holatlar ko'pincha eng ko'p uchraydigan xato manbai bo'ladi.

NEXT UP

Validation: Custom Rules & Error Messages

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

Request Validation Basics

So'rovlarni tekshirish (validatsiya) asoslari

Bank blankasini to'ldirganingizda, xodim uni QABUL QILISHDAN OLDIN tekshiradi: ism yozilganmi? summasi musbatmi? Agar biror maydon noto'g'ri bo'lsa, blanka SIZGA qaytariladi — bank tizimiga umuman KIRMAYDI. Request validation — API'da xuddi shu "xodim" vazifasini bajaradi: noto'g'ri ma'lumot BIZNES MANTIQQA (bazaga saqlash, hisoblash) YETMASDAN OLDIN rad etiladi.

example.go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"
)

type CreateBookRequest struct {
	Title  string  `json:"title"`
	Author string  `json:"author"`
	Price  float64 `json:"price"`
}

// validate — birinchi topilgan xatoni qaytaradi, hammasi to'g'ri bo'lsa "" qaytaradi
func validate(req CreateBookRequest) string {
	if strings.TrimSpace(req.Title) == "" {
		return "title bo'sh bo'lishi mumkin emas"
	}
	if strings.TrimSpace(req.Author) == "" {
		return "author bo'sh bo'lishi mumkin emas"
	}
	if req.Price <= 0 {
		return "price musbat son bo'lishi kerak"
	}
	return ""
}

func createHandler(w http.ResponseWriter, r *http.Request) {
	var req CreateBookRequest
	json.NewDecoder(r.Body).Decode(&req)

	if msg := validate(req); msg != "" {
		w.WriteHeader(http.StatusUnprocessableEntity)
		fmt.Fprint(w, msg)
		return
	}

	w.WriteHeader(http.StatusCreated)
	fmt.Fprint(w, "yaratildi")
}

func main() {
	req := httptest.NewRequest("POST", "/books", strings.NewReader(`{"title":"Go bilan tanishuv","price":45000}`))
	rec := httptest.NewRecorder()
	createHandler(rec, req)
	fmt.Println(rec.Code, rec.Body.String())
}

strings.TrimSpace(req.Title) == "" — nafaqat BO'SH matn (""), balki FAQAT bo'shliqlardan iborat matn (" ") ni ham "bo'sh" deb hisoblaydi — bu HAQIQIY validatsiyada juda TEZ-TEZ unutiladigan holat. req.Price <= 0 — narx NOL yoki MANFIY bo'lishi mumkin emasligini tekshiradi: bular "type-check" (JSON to'g'ri decode bo'ldimi) dan farqli, BIZNES QOIDA (business rule) validatsiyasi.

http.StatusUnprocessableEntity (422) — "HTTP Status Codes Done Right" darsida batafsil ko'radigan status: JSON STRUKTURASI to'g'ri (decode xatosiz o'tdi), lekin QIYMATLAR biznes qoidaga mos KELMAYDI. Bu — JSON umuman NOTO'G'RI formatlangan holatdagi 400 Bad Requestdan FARQLI holat.

>_ Exercise

Ombordagi son (Stock) uchun ham tekshiruv qo'shing.

  • CreateBookRequest'ga Stock int json:"stock" maydonini qo'shing
  • validate ichida: req.Stock < 0 bo'lsa "stock manfiy bo'lishi mumkin emas" qaytaring (Price tekshiruvidan KEYIN)
  • uchta holatni sinang: author yo'q, stock manfiy, va TO'LIQ to'g'ri so'rov — har birining natijasini chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Validatsiya — noto'g'ri ma'lumotni biznes mantiqqa yetmasdan oldin, ANIQ va TUSHUNARLI xato xabari bilan rad etadi; bo'sh matn va manfiy sonlar kabi "oddiy" holatlar ko'pincha eng ko'p uchraydigan xato manbai bo'ladi.

NEXT UP

Validation: Custom Rules & Error Messages