Meydan okuma 2 - HTTP servis
- Go kursu
- Orta seviye
- Ders 78/80
- 8 dk
net/http ile JSON döndüren bir servis yazarsın.
Meydan okuma: not defteri API'si
Bellekte notları tutan küçük bir HTTP servisi yazacaksın:
POST /notlar:{"metin":"..."}gövdesiyle not ekler,201ve eklenen notu (id dahil) döndürür. Metin boşsa400.GET /notlar: tüm notları JSON dizi olarak döndürür.
type Not struct {
ID int `json:"id"`
Metin string `json:"metin"`
}Notlar sync.Mutex ile korunan bir dilimde tutulur.
Plan
1) type Depo struct { mu sync.Mutex; notlar []Not; sonID int }. 2) mux.HandleFunc("POST /notlar", ...): gövdeyi çöz, boşsa 400, değilse kilitle, sonID++, ekle, 201 + JSON. 3) mux.HandleFunc("GET /notlar", ...): kilitle, listeyi JSON yaz. 4) httptest ile bir POST ve bir GET gönderip sonucu kontrol et.
Uygulama Servisi kur
Planı uygula. {"metin":"süt al"} gövdesiyle POST gönder, ardından GET yanıtının gövdesini yazdır.
Başlangıç kodu
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"sync"
)
func main() {
// buraya yaz
}Örnek çözüm
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"sync"
)
type Not struct {
ID int `json:"id"`
Metin string `json:"metin"`
}
type Depo struct {
mu sync.Mutex
notlar []Not
sonID int
}
func main() {
d := &Depo{notlar: []Not{}}
mux := http.NewServeMux()
mux.HandleFunc("POST /notlar", func(w http.ResponseWriter, r *http.Request) {
var n Not
if err := json.NewDecoder(r.Body).Decode(&n); err != nil || n.Metin == "" {
http.Error(w, "geçersiz not", http.StatusBadRequest)
return
}
d.mu.Lock()
d.sonID++
n.ID = d.sonID
d.notlar = append(d.notlar, n)
d.mu.Unlock()
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(n)
})
mux.HandleFunc("GET /notlar", func(w http.ResponseWriter, r *http.Request) {
d.mu.Lock()
defer d.mu.Unlock()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(d.notlar)
})
mux.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("POST", "/notlar", strings.NewReader(`{"metin":"süt al"}`)))
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, httptest.NewRequest("GET", "/notlar", nil))
fmt.Print(rec.Body.String())
}Beklenen çıktı
[{"id":1,"metin":"süt al"}]
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Not listesi boşken GET yanıtı <code>null</code> yerine <code>[]</code> olsun istiyorsan ne yaparsın?
- omitempty eklersin
- Yanıtı string olarak yazarsın
- Mümkün değildir
- Dilimi []Not{} ile başlatırsın Doğru cevap
Açıklama: nil dilim JSON'da null, boş ama nil olmayan dilim [] olarak kodlanır.
2 Oluşturuldu kodu
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.____)
json.NewEncoder(w).Encode(n)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(n)
Açıklama: Yeni kaynak eklendiğinde 201 Created döndürülür.
3 İstek ve yanıt
| Kavram | Anlamı |
|---|---|
POST geçerli metin |
201 + not |
POST boş metin |
400 |
GET |
200 + dizi |
PUT /notlar |
405 |