HTTP Service Communication
HTTP orqali servislar aloqasi
Ikki qo'shni davlat bir-biri bilan gaplashish uchun elchilar yuboradi, umumiy tilda muzokara qiladi. Mikroservislar ham xuddi shunday: ular bitta dastur ichida emas, ALOHIDA jarayonlarda (ko'pincha alohida serverlarda) ishlaydi, shuning uchun bir-biri bilan oddiy funksiya chaqiruvi orqali emas, balki tarmoq (odatda HTTP) orqali "gaplashadi".
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"net/http/httptest"
)
// UserService'ni chaqirganda nima qaytarishini simulyatsiya qilamiz
// (haqiqiy loyihada bu — alohida serverga HTTP so'rovi bo'lardi)
type userLookupTransport struct{}
func (t *userLookupTransport) RoundTrip(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewBufferString(`{"id":"u1","name":"Aziz"}`)),
Header: make(http.Header),
}, nil
}
// OrderService — UserService'ga HTTP orqali murojaat qiladi
func makeOrderHandler(client *http.Client) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
resp, err := client.Get("http://user-service.internal/users/u1")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Fprintf(w, "buyurtma yaratildi, foydalanuvchi: %s", string(body))
}
}
func main() {
client := &http.Client{Transport: &userLookupTransport{}}
orderHandler := makeOrderHandler(client)
req := httptest.NewRequest("POST", "/orders", nil)
rec := httptest.NewRecorder()
orderHandler(rec, req)
fmt.Println(rec.Body.String())
}Bu misolda ikkita "servis" o'rtasidagi haqiqiy aloqani ko'ramiz: makeOrderHandler (OrderService'ning handleri) client.Get("http://user-service.internal/...") orqali UserService'ga "murojaat qiladi". Haqiqiy production'da bu URL — UserService'ning haqiqiy tarmoq manzili bo'lardi. Bizning o'quv muhitimizda esa userLookupTransport UserService'ning ROLINI o'ynaydi ("HTTP Client Basics" darsida ko'rgan RoundTripper texnikasi) — bu bizga haqiqiy ikkita server ishga tushirmasdan, ularning ORASIDAGI ALOQA mantig'ini o'rganish imkonini beradi.
E'tibor bering: makeOrderHandler client *http.Clientni PARAMETR sifatida oladi ("Dependency Injection" darsida ko'rgan naqsh) — bu OrderService'ning o'zi qaysi HTTP klient bilan ishlashini "bilmasligi", faqat unga BERILGAN klientdan foydalanishini ta'minlaydi. Bu — production'da haqiqiy tarmoqqa ulanadigan klient, testda esa RoundTripper bilan sun'iy javob beradigan klient berish imkonini beradi.
>_ Exercise
InventoryService'ga murojaat qiluvchi handler yozing.
- •inventoryTransport yozing: RoundTrip {"in_stock":true} JSON'ini qaytarsin
- •makeCheckoutHandler(client) yozing: client.Get("http://inventory-service.internal/check") qilib, javobni "ombor holati: <javob>" formatida chop etsin
- •httptest bilan chaqirib, natijani chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
Mikroservislar bir-biri bilan HTTP orqali "gaplashadi"; klientni parametr sifatida berish (dependency injection) servislarni haqiqiy tarmoqsiz, ishonchli tarzda sinash imkonini beradi.
NEXT UP
Service Discovery Patterns
$ go run main.go
Kodingizni ishga tushiring