GoDasturchi
The Basic CRUD Handlers: Update & Delete

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.

example.go
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.

Hints (0/3)

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

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

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.

example.go
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.

Hints (0/3)

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