HTTP Status Codes Done Right
HTTP status kodlarini to'g'ri qo'llash
Svetofor faqat UCH RANGDA gapiradi (qizil, sariq, yashil), lekin HAR BIR haydovchi ularni BIR XIL tushunadi — chunki ma'no QAT'IY belgilangan. HTTP status kodlari ham xuddi shunday "universal til": 404 HAR DOIM "topilmadi", 409 HAR DOIM "ziddiyat" degani. Agar server "topilmadi" holatida 200 qaytarsa ("muvaffaqiyatli" degan ma'noda), bu — svetoforning QIZIL chirog'ida "yur" deyishga o'xshaydi: mijoz kutubxonalari (HTTP client'lar), monitoring tizimlari — BARCHASI adashadi.
package main
import (
"errors"
"fmt"
"net/http"
"net/http/httptest"
)
var (
ErrNotFound = errors.New("resurs topilmadi")
ErrValidation = errors.New("validatsiya xatosi")
ErrConflict = errors.New("bunday resurs allaqachon mavjud")
)
// statusFor — xato TURIGA qarab, TO'G'RI HTTP status kodini tanlaydi
func statusFor(err error) int {
switch {
case errors.Is(err, ErrNotFound):
return http.StatusNotFound
case errors.Is(err, ErrValidation):
return http.StatusUnprocessableEntity
case errors.Is(err, ErrConflict):
return http.StatusConflict
default:
return http.StatusInternalServerError
}
}
func handle(w http.ResponseWriter, err error) {
if err == nil {
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, "ok")
return
}
w.WriteHeader(statusFor(err))
fmt.Fprint(w, err.Error())
}
func main() {
for _, err := range []error{nil, ErrNotFound, ErrValidation, ErrConflict} {
rec := httptest.NewRecorder()
handle(rec, err)
fmt.Println(rec.Code, rec.Body.String())
}
}Sentinel xatolar (ErrNotFound, ErrValidation, ErrConflict — "Sentinel Errors" darsini eslang) va errors.Is — biznes mantiq ("bu resurs topilmadimi?") bilan HTTP QATLAMI ("qaysi status kod?") ni ALOHIDA saqlaydi: biznes kod HECH QACHON http paketini bilmaydi, FAQAT error qaytaradi; statusFor esa BITTA joyda, xatoni HTTP tiliga TARJIMA qiladi.
Har bir status — ANIQ ma'noga ega: 404 Not Found — so'ralgan narsa YO'Q; 409 Conflict — so'rov O'ZI to'g'ri, lekin joriy HOLAT bilan ZID (masalan bir xil ISBN'li kitob YARATISHGA urinish); 422 Unprocessable Entity — so'rov TUZILISHI to'g'ri, lekin QIYMATLAR noto'g'ri; 500 Internal Server Error — bu ODDIY holatlar EMAS, dasturdagi KUTILMAGAN nosozlik.
>_ Exercise
Avtorizatsiya xatosi uchun yangi holat qo'shing.
- •ErrUnauthorized = errors.New("avtorizatsiya talab qilinadi") sentinel xatosini qo'shing
- •statusFor ichida errors.Is(err, ErrUnauthorized) holatida http.StatusUnauthorized (401) qaytaring
- •scenarios ro'yxatiga ErrUnauthorized va errors.New("kutilmagan xato") (noma'lum xato) ni ham qo'shing, barcha 6 holatni chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
To'g'ri status kod tanlash — biznes xatosini (sentinel error) bitta markaziy statusFor funksiyasi orqali aniq HTTP koddga TARJIMA qilishdan iborat; noma'lum/kutilmagan xatolar har doim 500 ga tushadi, aniqlanganlar esa o'z ANIQ kodiga ega bo'ladi.
NEXT UP
Pagination: Limit & Offset
$ go run main.go
Kodingizni ishga tushiring