net/http paketining tuzilishi
net/http — Go standart kutubxonasidagi HTTP bilan ishlash paketi. U orqali web server ham, HTTP klient ham yoziladi. Go’da API qurishni boshlashdan oldin shu paketning qanday qismlardan iboratini tushunib olish foydali.
Tasavvur qiling, siz restoran ochdingiz. Eshik oldida mehmonlarni kutib oladigan xodim bor, u mehmonni kerakli stolga yo‘naltiradi. Har bir stolga alohida ofitsiant xizmat qiladi. net/httpda ham xuddi shunday: server ulanishlarni qabul qiladi, router so‘rovni kerakli joyga yo‘naltiradi, handler esa javobni tayyorlaydi.
Asosiy qismlar
net/http paketida ko‘p tur va funksiya bor. Lekin server tomonida deyarli hamma narsa quyidagi beshta tushuncha atrofida quriladi:
| Qism | Vazifasi |
|---|---|
http.Handler |
So‘rovga javob beradigan har qanday narsa uchun interfeys |
http.HandlerFunc |
Oddiy funksiyani Handlerga aylantiradigan tur |
http.ServeMux |
Router: URL yo‘liga qarab kerakli handlerni tanlaydi |
http.Server |
Portni tinglaydi, ulanishlarni boshqaradi |
*http.Request va http.ResponseWriter |
Kelgan so‘rov va yuboriladigan javob |
Klient tomonida esa http.Client va http.Response ishlatiladi. Ular bilan API ga so‘rov yuborish darsida tanishgansiz.
So‘rov serverga kelgandan boshlab javob qaytgunicha quyidagi yo‘lni bosib o‘tadi:
Klient
│ TCP ulanish
↓
http.Server → ulanishni qabul qiladi, HTTP so‘rovni o‘qiydi
│
↓
http.ServeMux → yo‘l va metodga qarab handlerni tanlaydi
│
↓
http.Handler → ServeHTTP(w, r) chaqiriladi
│
↓
http.ResponseWriter → javob klientga yoziladi
Endi har bir qismni alohida ko‘rib chiqamiz.
http.Handler interfeysi
Butun paketning markazida bitta kichik interfeys turadi:
ServeHTTP metodiga ega har qanday tur — handler. Server so‘rovni qabul qilgach, aynan shu metodni chaqiradi.
Misol
salomHandler oddiy struct. Unga ServeHTTP metodi qo‘shilgani uchun u http.Handler interfeysini qanoatlantiradi. Shu sababli uni to‘g‘ridan-to‘g‘ri ListenAndServega berish mumkin.
Bu yerda router yo‘q. Shuning uchun /, /abc yoki /users — qaysi yo‘lga murojaat qilmang, bir xil javob keladi.
Info
Handler struct bo‘lishi uning ichida bog‘liqliklarni saqlash imkonini beradi: database ulanishi, logger, konfiguratsiya va hokazo. Bu usul keyingi darslarda, ayniqsa clean architecture mavzusida ko‘p ishlatiladi.
http.HandlerFunc turi
Har bir handler uchun alohida struct yozish noqulay. Ko‘pincha oddiy funksiya yetarli. Buning uchun http.HandlerFunc turi bor:
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
HandlerFunc — funksiya turi. Unga ServeHTTP metodi biriktirilgan va bu metod funksiyaning o‘zini chaqiradi. Natijada mos imzoli istalgan funksiyani http.HandlerFunc(...) ko‘rinishida Handlerga aylantirish mumkin:
| main.go | |
|---|---|
http.HandlerFunc(salom) — funksiya chaqiruvi emas, balki tur o‘zgartirish (type conversion). salom funksiyasi HandlerFunc turiga o‘tkaziladi va endi uning ServeHTTP metodi bor.
Bu naqsh (pattern) Go’da juda keng tarqalgan. Middleware yozishda ham aynan shu usul ishlatiladi.
http.ServeMux — router
Haqiqiy API’da har bir yo‘l o‘z handleriga ega bo‘ladi: /books bitta ishni, /users boshqa ishni bajaradi. Yo‘lga qarab handler tanlash vazifasini multiplexer (qisqacha mux) yoki router bajaradi.
http.NewServeMux() yangi router yaratadi. mux.HandleFunc unga yo‘l va handlerni ro‘yxatdan o‘tkazadi.
E’tibor bering: ServeMuxning o‘zi ham ServeHTTP metodiga ega, ya’ni u ham http.Handler. Shu sababli ListenAndServega to‘g‘ridan-to‘g‘ri beriladi. Server so‘rovni mux’ga uzatadi, mux esa mos handlerni topib, uning ServeHTTP metodini chaqiradi.
"GET /books" ko‘rinishidagi yozuv Go 1.22 versiyasidan beri ishlaydi: pattern ichida HTTP metodi ham ko‘rsatiladi. Routing qoidalari URL routing darsida batafsil ko‘riladi.
DefaultServeMux
Oldingi darslarda http.HandleFunc("/", ...) va http.ListenAndServe(":8080", nil) yozgan edik. Bu yerda mux yaratilmagan, lekin routing ishlagan. Sababi paket ichida tayyor global router bor — http.DefaultServeMux.
http.HandleFunc("/", handler) // DefaultServeMux'ga qo‘shadi
http.ListenAndServe(":8080", nil) // nil → DefaultServeMux ishlatiladi
Kichik misollar uchun bu qulay. Lekin loyiha kattalashganda o‘z mux’ingizni yaratish yaxshiroq:
- global o‘zgaruvchi bo‘lgani uchun istalgan import qilingan paket unga handler qo‘shib qo‘yishi mumkin;
- testlarda har bir test uchun toza router yaratish oson bo‘ladi;
- qaysi yo‘llar ro‘yxatdan o‘tganini bitta joyda ko‘rish mumkin.
http.Server — server sozlamalari
http.ListenAndServe qulay funksiya, lekin uning ichida http.Server yaratiladi va ko‘p sozlamalar standart holatda qoladi. Server ustidan to‘liq nazorat kerak bo‘lsa, http.Serverni o‘zingiz yarating:
Maydonlarning ma’nosi:
Addr— tinglanadigan manzil va port.Handler— barcha so‘rovlarni qabul qiladigan asosiy handler, odatda router.ReadHeaderTimeout— so‘rov sarlavhalarini o‘qish uchun ajratilgan vaqt.ReadTimeout— butun so‘rovni, ya’ni sarlavha va tanani o‘qish uchun vaqt.WriteTimeout— javobni yozib tugatish uchun vaqt.IdleTimeout— keep-alive ulanish keyingi so‘rovni qancha kutishi.
Warning
http.ListenAndServe yaratgan serverda timeoutlar yo‘q. Sekin yoki qasddan juda sekin ma’lumot yuborayotgan klientlar ulanishlarni uzoq vaqt band qilib turishi mumkin. Production’da doim http.Serverni timeoutlar bilan yarating.
*http.Request va http.ResponseWriter
Har bir handler ikki argument oladi.
*http.Request — klient yuborgan so‘rov. Unda metod, URL, sarlavhalar, tana, cookie’lar va context bor:
r.Method // "GET", "POST", ...
r.URL.Path // "/books/42"
r.URL.Query() // query parametrlar
r.Header.Get("Accept")
r.Body // so‘rov tanasi (io.ReadCloser)
r.Context() // so‘rovga bog‘langan context
http.ResponseWriter — javobni yozish uchun interfeys. Uning uchta metodi bor:
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)
}
Header() orqali javob sarlavhalari o‘rnatiladi. WriteHeader() status kodni yuboradi. Write() esa javob tanasini yozadi.
Bu ikki obyekt bilan ishlash ResponseWriter va *Request obyektlari darsida batafsil ko‘riladi.
Paketdagi yordamchi funksiyalar
net/http tez-tez uchraydigan ishlar uchun tayyor funksiyalar ham beradi:
| Funksiya | Nima qiladi |
|---|---|
http.Error(w, xabar, kod) |
Matnli xato javobini yuboradi |
http.NotFound(w, r) |
404 page not found javobini yuboradi |
http.Redirect(w, r, url, kod) |
Klientni boshqa manzilga yo‘naltiradi |
http.ServeFile(w, r, yo‘l) |
Diskdagi faylni javob sifatida yuboradi |
http.FileServer(fs) |
Katalogdagi statik fayllarni tarqatadigan handler |
http.StripPrefix(prefiks, h) |
URL boshidagi prefiksni olib tashlab, keyingi handlerga uzatadi |
http.TimeoutHandler(h, vaqt, xabar) |
Handler berilgan vaqtda tugamasa, 503 qaytaradi |
http.MaxBytesReader(w, body, n) |
So‘rov tanasi hajmini cheklaydi |
Status kodlar uchun raqam o‘rniga konstantalardan foydalaning: http.StatusOK, http.StatusCreated, http.StatusNotFound. Metodlar uchun ham shunday: http.MethodGet, http.MethodPost. Bunday kod o‘qishga oson va xato yozish ehtimoli kam.
Misol: statik fayllar va handler birga
/static/logo.png so‘rovi kelganda StripPrefix yo‘lning boshidagi /static/ qismini olib tashlaydi. FileServer esa ./public/logo.png faylini qidiradi. /eski-sahifa ochilsa, klient 301 status bilan yangi manzilga yo‘naltiriladi.
E’tibor bering, mux.Handle tayyor http.Handlerni, mux.HandleFunc esa oddiy funksiyani qabul qiladi.
Klient tomoni
net/http faqat server uchun emas. Tashqi API’ga murojaat qilish uchun xuddi shu paketdagi http.Client ishlatiladi:
Server va klient bir xil Request, Response va Header turlaridan foydalanadi. Shu sababli bir tomonni bilsangiz, ikkinchisini o‘rganish oson kechadi.
Xulosa
Bu darsda net/http paketining asosiy qismlari bilan tanishdik:
http.Handler—ServeHTTPmetodiga ega har qanday tur;http.HandlerFunc— oddiy funksiyani handlerga aylantiradi;http.ServeMux— so‘rovni yo‘l va metodga qarab kerakli handlerga yo‘naltiradi;http.Server— portni tinglaydi, timeoutlar va boshqa sozlamalarni boshqaradi;*http.Requestvahttp.ResponseWriter— kirish va chiqish.
Bu qismlarning barchasi Handler interfeysi orqali bir-biriga ulanadi. Keyingi darsda http.HandleFunc va http.ListenAndServe funksiyalarini batafsil ko‘rib chiqamiz.