Menyimpan Data: Store In-Memory
Membuat penyimpanan todo di memori dengan map, penghitung ID, dan sync.Mutex agar aman dipakai banyak request.
Kenapa butuh "store"?
API perlu tempat menyimpan data antar request. Untuk belajar, kita pakai penyimpanan di memori (sebuah map) — sederhana dan tanpa database. Konsekuensinya: data hilang saat server dimatikan. Cara kerjanya sama dengan database sungguhan, jadi nanti mudah diganti.
Rancangan Store
type Store struct {
mu sync.Mutex // kunci pengaman
items map[int]Todo // id → todo
nextID int // ID untuk todo berikutnya
}
func NewStore() *Store {
return &Store{items: map[int]Todo{}, nextID: 1}
}
map[int]Todo— kamus yang menyimpan todo berdasarkan ID, sehingga mencari ID tertentu sangat cepat.nextID— penghitung. Setiap todo baru memakai nilai ini lalu penghitung dinaikkan, sehingga ID tidak pernah kembar.NewStore()— "pembuat" yang menyiapkan map (map kosong harus dibuat dulu sebelum dipakai menulis).
Kenapa ada sync.Mutex?
Server Go melayani banyak request sekaligus, masing-masing di goroutine sendiri. Jika dua request menulis ke map yang sama pada saat bersamaan, program bisa crash. sync.Mutex bekerja seperti kunci kamar mandi: hanya satu yang boleh masuk.
s.mu.Lock() // kunci: tunggu giliran
defer s.mu.Unlock() // buka kunci otomatis saat fungsi selesai
Operasi dasar pada map
s.items[id] = todo // simpan / timpa
t, ok := s.items[id] // baca; ok = false jika id tidak ada
delete(s.items, id) // hapus
Method pada pointer
Method Store memakai receiver pointer (s *Store) supaya semua pemanggil memakai satu Store yang sama (bukan salinan).
func (s *Store) Add(title string) Todo {
s.mu.Lock()
defer s.mu.Unlock()
todo := Todo{ID: s.nextID, Title: title} // buat todo
s.items[todo.ID] = todo // simpan
s.nextID++ // naikkan penghitung
return todo
}