Go / HTTP server үндэс

HTTP server үндэс

Go-ийн net/http package нь хурдан, найдвартай HTTP сервер бичих бүх хэрэгслийг суурилагдсан байдлаар өгдөг. Нэмэлт framework шаардлагагүй — энгийн API-д цэвэр net/http хангалттай.

Анхны HTTP сервер

Дөнгөж хэдэн мөр кодоор HTTP сервер ажиллуулж болно:

go
package main

import (
    "fmt"
    "net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Сайн уу, дэлхий!")
}

func main() {
    http.HandleFunc("/", helloHandler)

    fmt.Println("Сервер 8080 порт дээр ажиллаж байна...")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        fmt.Println("Сервер эхлэхэд алдаа:", err)
    }
}

Ажиллуулаад http://localhost:8080 хаяг руу хандвал "Сайн уу, дэлхий!" харагдана.

http.ResponseWriter — хариу бичих хэрэгсэл. *http.Request — ирсэн хүсэлтийн мэдээлэл.

JSON хариу буцаах

Бодит API-д HTML биш JSON хариу буцаадаг:

go
package main

import (
    "encoding/json"
    "net/http"
)

type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
    City string `json:"city"`
}

func getUserHandler(w http.ResponseWriter, r *http.Request) {
    user := User{ID: 1, Name: "Бат-Эрдэнэ", City: "Улаанбаатар"}

    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(user)
}

func notFoundHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(http.StatusNotFound)
    json.NewEncoder(w).Encode(map[string]string{
        "error": "хуудас олдсонгүй",
    })
}

func main() {
    http.HandleFunc("/user", getUserHandler)
    http.HandleFunc("/404", notFoundHandler)

    http.ListenAndServe(":8080", nil)
}

w.Header().Set(...) нь хариу илгээхийн өмнө дуудагдах ёстой. WriteHeader дуудсаны дараа header өөрчлөх боломжгүй.

HTTP method шалгах

GET, POST зэрэг method-ийг ялгаж зохицуулах:

go
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

type Product struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Price int    `json:"price"`
}

var products = []Product{
    {ID: 1, Name: "Дэвтэр", Price: 2000},
    {ID: 2, Name: "Харандаа", Price: 500},
}

func productsHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")

    switch r.Method {
    case http.MethodGet:
        json.NewEncoder(w).Encode(products)

    case http.MethodPost:
        var newProduct Product
        err := json.NewDecoder(r.Body).Decode(&newProduct)
        if err != nil {
            w.WriteHeader(http.StatusBadRequest)
            json.NewEncoder(w).Encode(map[string]string{"error": "буруу өгөгдөл"})
            return
        }
        newProduct.ID = len(products) + 1
        products = append(products, newProduct)
        w.WriteHeader(http.StatusCreated)
        json.NewEncoder(w).Encode(newProduct)

    default:
        w.WriteHeader(http.StatusMethodNotAllowed)
        fmt.Fprintln(w, "Энэ method зөвшөөрөгдөөгүй")
    }
}

func main() {
    http.HandleFunc("/products", productsHandler)
    fmt.Println("Сервер ажиллаж байна: http://localhost:8080")
    http.ListenAndServe(":8080", nil)
}

Query parameter унших

URL-ийн ?key=value хэсгийг унших:

go
package main

import (
    "encoding/json"
    "net/http"
)

func searchHandler(w http.ResponseWriter, r *http.Request) {
    // /search?q=golang&limit=10
    query := r.URL.Query().Get("q")
    limit := r.URL.Query().Get("limit")

    if query == "" {
        w.WriteHeader(http.StatusBadRequest)
        json.NewEncoder(w).Encode(map[string]string{
            "error": "q параметр шаардлагатай",
        })
        return
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(map[string]string{
        "query": query,
        "limit": limit,
        "result": query + "-тай холбоотой үр дүн",
    })
}

func main() {
    http.HandleFunc("/search", searchHandler)
    http.ListenAndServe(":8080", nil)
}

Хөтчид http://localhost:8080/search?q=golang&limit=5 гэж хандвал JSON хариу харагдана.

Дараагийн хичээлд:

URL параметр (/users/123) задлах, middleware нэмэх, сервер илүү цэгцтэй зохион байгуулах — HTTP router ба handler-ийн дэвшилтэт хэрэглээг судална.