Skip to content

Go http 패키지

Go 언어 표준 라이브러리의 net/http 패키지는 매우 훌륭하며, HTTP 클라이언트와 서버 구현을 완벽하게 제공합니다. 단 몇 줄의 코드만으로 매우 간단한 HTTP 서버를 구축할 수 있습니다.

거의 모든 Go 언어 웹 프레임워크는 기존 http 패키지를 기반으로 캡슐화하고 수정한 것이므로, 다른 프레임워크를 배우기 전에 http 패키지를 먼저 익히는 것을 강력히 권장합니다.

Get 예시

Http 관련 지식에 대해서는 여기서 더 이상 설명하지 않겠습니다. 더 자세히 알고 싶다면 직접 검색해 보시기 바랍니다.

go
func main() {
  resp, err := http.Get("https://baidu.com")
  if err != nil {
    fmt.Println(err)
    return
  }
  defer resp.Body.Close()
  content, err := io.ReadAll(resp.Body)
  fmt.Println(string(content))
}

Http 패키지의 함수를 직접 호출하기만 하면 간단한 요청을 보낼 수 있으며, 포인터와 오류를 반환합니다. 호출 후 반드시 수동으로 닫아야 합니다.

Post 예시

go
func main() {
   person := Person{
      UserId:   "120",
      Username: "jack",
      Age:      18,
      Address:  "usa",
   }

   json, _ := json.Marshal(person)
   reader := bytes.NewReader(json)

   resp, err := http.Post("https://golang.org", "application/json;charset=utf-8", reader)
   if err != nil {
      fmt.Println(err)
   }
   defer resp.Body.Close()
}

클라이언트

일반적으로 우리는 위의 방법을 직접 사용하지 않고, 클라이언트를 직접 구성하여 더욱 세밀한 요구사항을 충족시킵니다. 이를 위해 http.Client{} 구조체를 사용하며, 제공되는 설정 항목은 총 네 가지입니다:

  • Transport: Http 클라이언트 데이터 전송 관련 설정 항목, 없으면 기본 전략 사용
  • Timeout: 요청 타임아웃 시간 설정
  • Jar: Cookie 관련 설정
  • CheckRedirect: 리디렉션 설정

간단한 예시

go
func main() {
  client := &http.Client{}
  request, _ := http.NewRequest("GET", "https://golang.org", nil)
  resp, _ := client.Do(request)
  defer resp.Body.Close()
}

header 추가

go
func main() {
   client := &http.Client{}
   request, _ := http.NewRequest("GET", "https://golang.org", nil)
   request.Header.Add("Authorization","123456")
   resp, _ := client.Do(request)
   defer resp.Body.Close()
}

자세한 설정에 대해서는 여기서 너무 많이 설명하지 않겠습니다. 직접 알아보세요.

서버

Go 의 경우 HTTP 서버를 생성하는 데는 한 줄의 코드만 필요합니다.

첫 번째 매개변수는 감시 주소이고, 두 번째 매개변수는 프로세서이며, 비어있으면 기본 프로세서를 사용합니다. 대부분의 경우 기본 프로세서인 DefaultServeMux 를 사용하면 됩니다.

go
http.ListenAndServe("localhost:8080", nil)

사용자 정의

물론 서버를 사용자 정의하여 구성할 수도 있습니다.

go
func main() {
   server := &http.Server{
      Addr:              ":8080",
      Handler:           nil,
      TLSConfig:         nil,
      ReadTimeout:       0,
      ReadHeaderTimeout: 0,
      WriteTimeout:      0,
      IdleTimeout:       0,
      MaxHeaderBytes:    0,
      TLSNextProto:      nil,
      ConnState:         nil,
      ErrorLog:          nil,
      BaseContext:       nil,
      ConnContext:       nil,
   }
   server.ListenAndServe()
}

자세한 설정에 대해서는 직접 알아보세요.

라우트

먼저 Handler 인터페이스의 ServeHTTP(ResponseWriter, *Request) 메서드를 구현하는 사용자 정의 구조체를 정의한 후 http.Handle() 함수를 호출하면 됩니다.

go
func main() {
   http.Handle("/index", &MyHandler{})
   http.ListenAndServe(":8080", nil)
}

type MyHandler struct {
}

func (h *MyHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
   fmt.Println("my implement")
}

하지만 매번 구조체를 사용자 정의하는 것은 매우 번거롭습니다. http.HandlerFunc 함수를 직접 사용할 수 있으며, 처리 함수만 작성하면 되므로 구조체를 생성할 필요가 없습니다. 내부적으로는 어댑터 타입인 HandlerFunc 를 사용합니다. HandlerFunc 타입은 어댑터로, 일반 함수를 HTTP 프로세서로 사용할 수 있게 합니다. f 가 적절한 서명의 함수인 경우 HandlerFunc(f) 는 f 를 호출하는 Handler 입니다.

go
func main() {
   http.HandleFunc("/index", func(responseWriter http.ResponseWriter, request *http.Request) {
      fmt.Println(responseWriter, "index")
   })
   http.ListenAndServe(":8080", nil)
}

ServeMux 는 핵심 구조체로, 기본 메서드를 구현하며, DefaultServeMux 는 기본 인스턴스입니다.

리버스 프록시

http 패키지는 즉시 사용 가능한 리버스 프록시 기능을 제공합니다.

go
func main() {
   http.HandleFunc("/forward", func(writer http.ResponseWriter, request *http.Request) {
      director := func(request *http.Request) {
         request.URL.Scheme = "https"
         request.URL.Host = "golang.org"
         request.URL.Path = "index"
      }

      proxy := httputil.ReverseProxy{Director: director}
      proxy.ServeHTTP(writer, request)

   })

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

위 코드는 모든 요청을 https://golang.org/index 로 전달합니다.

Golang by www.golangdev.cn edit