Content Negotiation
Kontent kelishuvi (content negotiation)
Restoran ofitsianti mijozdan "qaysi tilda menyu kerak?" deb SO'RAYDI va shu tilda menyu OLIB KELADI — bir xil taomlar, lekin TURLI taqdimotda. HTTP'da mijoz Accept sarlavhasi orqali "menga QAYSI formatda javob kerak" deb AYTADI (masalan application/json yoki text/plain), server esa BIR XIL ma'lumotni SO'RALGAN formatda qaytaradi — bu content negotiation (kontent kelishuvi) deb ataladi.
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
)
type Book struct {
ID string `json:"id"`
Title string `json:"title"`
Author string `json:"author"`
Price float64 `json:"price"`
}
func main() {
book := Book{ID: "1", Title: "Go bilan tanishuv", Author: "A. Karimov", Price: 45000}
mux := http.NewServeMux()
mux.HandleFunc("GET /books/{id}", func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Accept") == "text/plain" {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintf(w, "%s — %s (%.0f so'm)", book.Title, book.Author, book.Price)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(book)
})
req1 := httptest.NewRequest("GET", "/books/1", nil)
req1.Header.Set("Accept", "text/plain")
rec1 := httptest.NewRecorder()
mux.ServeHTTP(rec1, req1)
fmt.Println(rec1.Body.String())
req2 := httptest.NewRequest("GET", "/books/1", nil)
req2.Header.Set("Accept", "application/json")
rec2 := httptest.NewRecorder()
mux.ServeHTTP(rec2, req2)
fmt.Print(rec2.Body.String())
}r.Header.Get("Accept") — mijoz "men QANDAY javob kutayapman" deb aytgan sarlavha. Handler BIR XIL book MA'LUMOTIDAN ikki TURLI taqdimot (JSON yoki oddiy matn) yaratadi — bu "Interface Design" darsidagi "ma'lumot va uning TAQDIMOTINI ajratish" g'oyasining HTTP darajasidagi ko'rinishi.
Bunday yondashuv AYNIQSA foydali: masalan brauzerlar odatda text/html yoki */* so'raydi, mobil ilovalar esa KO'PINCHA application/json — BIR XIL server, BIR XIL endpoint, lekin MIJOZGA MOS formatda javob beradi.
>_ Exercise
Standart holatni va QO'LLAB-QUVVATLANMAYDIGAN formatni ham to'g'ri boshqaring.
- •handlerni switch bilan yozing: "text/plain" -> matn, ""/"*/*"/"application/json" -> JSON, BOSHQA HAR QANDAY qiymat -> http.StatusNotAcceptable (406) va "qo'llab-quvvatlanmaydigan format" matni
- •Accept sarlavhasiz so'rov yuborib, STANDART holatda JSON qaytishini tekshiring
- •"application/xml" bilan so'rov yuborib, 406 qaytishini tekshiring
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Content negotiation — BIR XIL ma'lumotni Accept sarlavhasiga qarab TURLI formatda (JSON, matn) qaytaradi; qo'llab-quvvatlanmaydigan format so'ralganda esa, 406 status bilan buni ANIQ bildirish kerak.
NEXT UP
Testing Handlers: Table-Driven Tests
$ go run main.go
Kodingizni ishga tushiring