REST API
REST API
Shu paytgacha qurgan barcha qismlar (saqlash, indeks, so'rov tili, statistika) hali FAQAT Go kodi ICHIDA ishlatilardi. Oxirgi qadam — bularni HTTP orqali tashqi dunyoga OCHISH: har bir servis o'z loglarini YUBORISHI, va foydalanuvchi ularni QIDIRISHI mumkin bo'lgan REST API.
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"sync"
)
type LogEntry struct {
Level string `json:"level"`
Service string `json:"service"`
Message string `json:"message"`
}
type LogStore struct {
mu sync.Mutex
entries []LogEntry
}
func NewLogStore() *LogStore { return &LogStore{} }
func (s *LogStore) Append(e LogEntry) {
s.mu.Lock()
defer s.mu.Unlock()
s.entries = append(s.entries, e)
}
func (s *LogStore) FilterByLevel(level string) []LogEntry {
s.mu.Lock()
defer s.mu.Unlock()
var result []LogEntry
for _, e := range s.entries {
if e.Level == level {
result = append(result, e)
}
}
return result
}
// makeIngestHandler — yangi log qabul qilish uchun POST /logs
func makeIngestHandler(store *LogStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var entry LogEntry
if err := json.NewDecoder(r.Body).Decode(&entry); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
store.Append(entry)
w.WriteHeader(http.StatusCreated)
}
}
func main() {
store := NewLogStore()
handler := makeIngestHandler(store)
body := `{"level":"ERROR","service":"payments","message":"muvaffaqiyatsiz"}`
req := httptest.NewRequest("POST", "/logs", strings.NewReader(body))
rec := httptest.NewRecorder()
handler(rec, req)
fmt.Println(rec.Code, len(store.entries))
}makeIngestHandler — "Shorten Endpoint" va "HTTP API for Task Queue" darslarida ko'rgan aynan shu naqsh: JSON so'rov TANASINI o'qib, ichki Storega saqlab, mos STATUS kod bilan javob beradi. http.StatusCreated (201) — yangi RESURS (bu holatda, yangi log yozuvi) MUVAFFAQIYATLI yaratilganini bildiradigan, "RESTful API Design" darsida ko'rgan aniq status kod.
Bu bitta endpoint — BUTUN Log Aggregator tizimining "eshigi": endi HAR QANDAY servis (Go, Python, JavaScript — TIL FARQI YO'Q, chunki HTTP+JSON UNIVERSAL) shu manzilga log yuborishi mumkin. Keyingi qadam — qidiruv va statistika uchun HAM shunga o'xshash endpoint'lar qo'shish ("GET /logs?level=ERROR" kabi).
>_ Exercise
Level bo'yicha filtrlab loglarni qaytaruvchi GET endpoint qo'shing.
- •makeSearchHandler(store *LogStore) http.HandlerFunc yozing: r.URL.Query().Get("level") orqali level parametrini oling
- •store.FilterByLevel(level) natijasini json.NewEncoder(w).Encode(...) orqali javob sifatida yozing
- •3 ta log qo'shing (2 tasi ERROR, 1 tasi INFO), "/logs?level=ERROR" so'rovi yuboring va javob tanasini chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
REST API orqali Log Aggregator'ning barcha ichki qobiliyatlari (saqlash, filtrlash) HTTP so'rovlari orqali istalgan tashqi dastur uchun ochiladi — bu butun tizimni til va platformadan mustaqil, universal xizmatga aylantiradi.
$ go run main.go
Kodingizni ishga tushiring