Middleware integratsiyasi
gorilla/mux middleware’lar bilan ishlash uchun Use metodini beradi. U standart func(http.Handler) http.Handler imzosidagi middleware’larni qabul qiladi. Shu sababli oldingi darslarda yozilgan logging, recoverer, auth va ruxsat middleware’lari hech qanday o‘zgarishsiz ishlaydi.
Lekin gorilla/mux middleware’larining bitta muhim xususiyati bor. U ko‘pchilikni chalg‘itadi, shuning uchun bu darsda unga alohida to‘xtalamiz.
r.Use
Use bir nechta middleware’ni birdaniga ham qabul qiladi:
Middleware’lar qo‘shilgan tartibda ishlaydi: birinchi qo‘shilgani eng tashqi qatlam bo‘ladi.
Bu Middleware va logging asoslari darsidagi chain funksiyasi bilan bir xil tartib.
mux.MiddlewareFunc
Kutubxonada maxsus tur bor:
Use aynan shu turni qabul qiladi. Oddiy func(http.Handler) http.Handler imzosidagi funksiyalar unga avtomatik mos keladi, shuning uchun tur o‘zgartirish shart emas.
Muhim xususiyat: middleware faqat mos kelgan marshrutda ishlaydi
r.Use bilan qo‘shilgan middleware’lar faqat biror marshrut mos kelganda ishlaydi. So‘rov hech bir marshrutga mos kelmasa, 404 javobi middleware’larni chetlab o‘tadi.
| So‘rov | Middleware ishlaydimi? |
|---|---|
GET /books |
✅ ha |
GET /authors → 404 |
❌ yo‘q |
POST /books → 405 |
❌ yo‘q |
Buning amaliy oqibatlari bor:
- Logging.
404va405so‘rovlari logga tushmaydi. Kimdir API’ni skaner qilayotgani, ya’ni mavjud bo‘lmagan yo‘llarni ketma-ket tekshirib chiqayotgani ko‘rinmay qoladi. - CORS. Brauzer yuboradigan
OPTIONSpreflight so‘rovi uchun alohida marshrut bo‘lmasa, u405oladi. CORS middleware’i esa umuman ishlamaydi. - Recoverer va request ID.
NotFoundHandlerichidagi xatolar ushlanmaydi.
Yechim: routerni tashqaridan o‘rash
Barcha so‘rovlarda ishlashi kerak bo‘lgan middleware’lar r.Use orqali emas, butun router’ni o‘rash orqali ulanadi:
r := mux.NewRouter()
r.HandleFunc("/books", listBooks).Methods("GET")
var handler http.Handler = r
handler = logging(handler) // barcha so‘rovlar, jumladan 404
handler = recoverer(handler) // eng tashqi qatlam
http.ListenAndServe(":8080", handler)
Qoida:
- router’ni tashqaridan o‘rash — logging, recoverer, request ID, CORS, xavfsizlik sarlavhalari. Ular har qanday so‘rov uchun ishlashi kerak;
r.Useyokisubrouter.Use— auth, ruxsat tekshiruvi. Ular faqat mavjud marshrutlar uchun ma’noga ega.
Subrouter middleware’lari
r := mux.NewRouter()
api := r.PathPrefix("/api/v1").Subrouter()
api.HandleFunc("/books", listBooks).Methods("GET")
private := api.PathPrefix("").Subrouter()
private.Use(auth.Require)
private.HandleFunc("/me", me).Methods("GET")
private.HandleFunc("/books", createBook).Methods("POST")
admin := api.PathPrefix("/admin").Subrouter()
admin.Use(auth.Require, RequireRole(RoleAdmin))
admin.HandleFunc("/stats", stats).Methods("GET")
api.PathPrefix("").Subrouter()— prefiksi bo‘sh subrouter. U yangi yo‘l qo‘shmaydi, faqat bir guruh marshrutlarni umumiy middleware bilan birlashtiradi.GET /api/v1/booksochiq,POST /api/v1/booksesa himoyalangan. Ikkalasi bir yo‘lda, lekin turli guruhlarda joylashgan.- Ota router’ning middleware’lari ichki subrouter’larga ham qo‘llanadi. Ichki subrouter’ning middleware’lari esa ulardan keyin ishlaydi.
CORS preflight
Brauzer boshqa domendan Content-Type: application/json bilan POST so‘rov yuborishdan oldin preflight so‘rovini yuboradi: OPTIONS /api/v1/books. gorilla/muxda OPTIONS metodli marshrut bo‘lmasa, bu so‘rov 405 oladi va brauzer asosiy so‘rovni yubormaydi.
Kutubxonada mux.CORSMethodMiddleware bor. U Access-Control-Allow-Methods sarlavhasini marshrutdagi metodlarga qarab to‘ldiradi. Lekin u faqat OPTIONS metodi e’lon qilingan marshrutlarda ishlaydi va CORS’ning boshqa sarlavhalarini qo‘ymaydi.
Amalda CORS’ni router’ni tashqaridan o‘raydigan alohida middleware bilan hal qilish soddaroq. Bunday middleware OPTIONS so‘rovini router’ga yetkazmasdan o‘zi javob beradi. CORS’ni to‘liq yozish Security headers & CORS darsida ko‘riladi.
To‘liq misol
curl -i http://localhost:8080/api/v1/books
curl -X POST http://localhost:8080/api/v1/books
curl -X POST -H "Authorization: Bearer demo-token" http://localhost:8080/api/v1/books
curl http://localhost:8080/api/v1/authors
curl -X DELETE http://localhost:8080/api/v1/books
Klient javoblari:
HTTP/1.1 200 OK
Content-Type: application/json
X-Route: /api/v1/books
...
{"message":"kitoblar ro‘yxati"}
{"error":"tizimga kiring"}
{"message":"kitob yaratildi"}
{"error":"endpoint topilmadi"}
{"error":"endpoint topilmadi"}
Server loglari:
2026/09/30 10:00:01 GET /api/v1/books → 200 (41µs)
2026/09/30 10:00:02 POST /api/v1/books → 401 (22µs)
2026/09/30 10:00:03 POST /api/v1/books → 200 (18µs)
2026/09/30 10:00:04 GET /api/v1/authors → 404 (15µs)
2026/09/30 10:00:05 DELETE /api/v1/books → 404 (9µs)
Natijalarni tahlil qilamiz:
loggingrouter’ni tashqaridan o‘ragani uchun marshrut topilmagan404so‘rovlari ham logga tushdi.mux.CurrentRoute(r)middleware ichida qaysi marshrut mos kelganini beradi. Bu metrikalarni yo‘l shabloni bo‘yicha guruhlash uchun foydali. Masalan,/books/1,/books/2va/books/3alohida-alohida emas, bitta/books/{id}sifatida hisoblanadi.GET /api/v1/booksochiq,POSTesarequireTokenbilan himoyalangan.DELETE /api/v1/booksso‘rovi405emas,404oldi. Bugorilla/muxning ma’lum xususiyati: yo‘l bir nechta subrouter’ga bo‘lingan bo‘lsa, metod mos kelmagan holat ba’zan "marshrut topilmadi" deb baholanadi.405javobi muhim bo‘lsa, bitta yo‘lning barcha metodlarini bitta subrouter ichida e’lon qiling va natijani test bilan tekshiring.
Xulosa
r.Usestandartfunc(http.Handler) http.Handlermiddleware’larini qabul qiladi va ularni qo‘shilgan tartibda ishlatadi.r.Usemiddleware’lari faqat mos kelgan marshrutlarda ishlaydi.404va405ularni chetlab o‘tadi.- Barcha so‘rovlar uchun zarur middleware’lar, ya’ni logging, recoverer va CORS, router’ni tashqaridan o‘raydi.
- Auth va ruxsat middleware’lari subrouter’larga
Useorqali ulanadi. mux.CurrentRoute(r)middleware ichida mos kelgan marshrutni aniqlash imkonini beradi.
Shu bilan gorilla/mux bo‘limi tugadi. Keyingi bo‘limda to‘liq framework — Gin bilan tanishamiz.