The Basic CRUD Handlers: Update & Delete
Asosiy CRUD handlerlar: Yangilash va O'chirish
Kutubxonachi eski kartochkani BUTUNLAY yangisiga almashtirishi mumkin (masalan kitobning YANGI nashri chiqqanda) — bu Update. Yoki kitob yo'qolgan/eskirgan bo'lsa, kartochkani katalogdan OLIB TASHLASHI mumkin — bu Delete. Ikkalasi ham MAVJUD yozuv ustida ishlaydi, shuning uchun avval "bu ID haqiqatan mavjudmi?" tekshiruvi KERAK.
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"sync"
)
type Book struct {
ID string `json:"id"`
Title string `json:"title"`
Author string `json:"author"`
Price float64 `json:"price"`
}
type BookStore struct {
mu sync.Mutex
books map[string]*Book
}
func NewBookStore() *BookStore { return &BookStore{books: make(map[string]*Book)} }
// Update — TO'LIQ almashtirish (PUT semantikasi): eski qiymatlar E'TIBORGA OLINMAYDI
func (s *BookStore) Update(id, title, author string, price float64) (*Book, bool) {
s.mu.Lock()
defer s.mu.Unlock()
if _, ok := s.books[id]; !ok {
return nil, false
}
book := &Book{ID: id, Title: title, Author: author, Price: price}
s.books[id] = book
return book, true
}
func main() {
store := NewBookStore()
store.books["1"] = &Book{ID: "1", Title: "Go bilan tanishuv", Author: "A. Karimov", Price: 45000}
mux := http.NewServeMux()
mux.HandleFunc("PUT /books/{id}", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
var req struct {
Title string `json:"title"`
Author string `json:"author"`
Price float64 `json:"price"`
}
json.NewDecoder(r.Body).Decode(&req)
book, ok := store.Update(id, req.Title, req.Author, req.Price)
if !ok {
w.WriteHeader(http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(book)
})
body := strings.NewReader(`{"title":"Go bilan tanishuv (2-nashr)","author":"A. Karimov","price":49000}`)
req := httptest.NewRequest("PUT", "/books/1", body)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
fmt.Println(rec.Code)
fmt.Println(rec.Body.String())
}Update — avval if _, ok := s.books[id]; !ok bilan ID MAVJUDLIGINI tekshiradi, TOPILMASA false qaytaradi, handler esa buni ko'rib 404 Not Found yozadi. Bu — "mavjud bo'lmagan narsani yangilab bo'lmaydi" degan oddiy, lekin MUHIM qoida: aks holda PUT /books/999 bo'sh joydan YANGI kitob yaratib qo'yishi mumkin edi, bu esa POST bilan PUTning chegarasini XIRALASHTIRADI.
Diqqat qiling: PUT — TO'LIQ almashtirish, ya'ni so'rovda YUBORILMAGAN maydon (masalan author unutilsa) BO'SH qiymat bilan YOZILADI. Bu — "Partial Updates with PATCH" darsida ko'radigan PATCH bilan FARQ qiladigan asosiy xususiyat: PATCH faqat YUBORILGAN maydonlarni o'zgartiradi, PUT esa BUTUN resursni yangi qiymat bilan ALMASHTIRADI.
>_ Exercise
Kitobni o'chirish (Delete) imkoniyatini qo'shing.
- •BookStore'ga Delete(id string) bool metodini qo'shing: ID mavjud bo'lmasa false, mavjud bo'lsa delete(s.books, id) qilib true qaytaring
- •"DELETE /books/{id}" handlerini yozing: Delete natijasi false bo'lsa 404, true bo'lsa 204 (http.StatusNoContent) qaytaring
- •"GET /books/{id}" handlerini yozing (faqat mavjudlikni tekshiradi: 200 yoki 404)
- •kitobni o'chiring, KEYIN GET bilan tekshiring, SO'NG YANA o'chirishga urinib ko'ring — har uch status kodni chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Update (PUT) va Delete (DELETE) — avval resurs MAVJUDLIGINI tekshiradi, faqat shundan keyin amal bajaradi; PUT resursni TO'LIQ almashtiradi, Delete esa uni butunlay olib tashlaydi.
NEXT UP
Request Validation Basics
$ go run main.go
Kodingizni ishga tushiring