GoDasturchi
REST API

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.

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

Hints (0/3)

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.

Finish
OUTPUT

$ go run main.go
Kodingizni ishga tushiring

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.

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

Hints (0/3)

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.