2021년 3월 24일 수요일

[Golang] net/http 패키지를 이용한 웹서버 제작

 net/http 패키지를 이용한 웹서버 제작

golang에서 기본적으로 제공하는  net/http패키지를 이용해서 웹서버를 구축할수 있다. 일단 얼마나 간단한지 보자.

1.초간단 서버 구동 

package main

import (
  "fmt"
  "net/http"
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
      fmt.Fprintln(w, r.Method, "welcome Go lang")
  })
  http.ListenAndServe(":8080", nil)
}

/*
or 

import "log"
fun printHello(w http.ResponseWriter, r *http.Request) {
      fmt.Fprintln(w, r.Method, "welcome Go lang"
}
func main() {
  http.HandleFunc("/", printHello)

   if err := http.ListenAndServe(":8000", nil); err != nil {
        log.Fatal("ListenAndServe: ", err)
    }

}

*/

 

웹서버를 구동할수 있는 net/http 패키지를 제공하기 때문에 단 몇줄만으로도 웹서버를 구동하여 응답문자와 접속메소드를 출력할수 있다.

간단한 echo(응답) 서버이지만 , 여러개의 endpoint를 생성한다면 간단한 API서버를 금방 만들수 있다. 

API서버는 여러개의 endpoint를 가지는데 다루기쉬운 Restful(패스파라메터와 요청파라메터로 구성된) 방식으로 만들기 위해서는 Router라는 것을 만들어 사용자가 요청한 페이지와 파라메터에 맞게 적절한 응답을 해주어야 한다.


  1. net/http
    net / http 패키지는  HTTP 클라이언트와 HTTP 서버를 구현하는 데 필요한 기능을 제공하고 있다. 

  2. http.ListenANdServe
    서버를 기동 시겨준다. 

  3. HandlerFunc
    golang에서 제공하는 기본적인  주소매칭방식인 DefaultServeMux 으로 url주소패턴과 실행될 함수를 지정한다.
    두번째 인자로 handler 를 받게 되는데 이곳에서 응답처리와 클라이언트로부터의 요청에 대한 처리를 수행한다.

    pattern : url 패턴이다
    handler : Reponse(응답) 과  Request(요청된것) 을 인자로 받는 함수이다.

  4. Handle
    HandlerFunc 는 항상 지정된 같은 함수의 루틴일 실행하게 되는데, 같은 url패턴이라도 상황에 따라, 예를들면  로그인전/후의 메인페이지  등과 같이 다른 내용을 보여야 할떄가 있다. 이럴때는 처리해서 보여줄 페이지를 동적으로 구성해야 하는데 Handle 함수의 두번째 인자에 ServerHttp 메소드를 가진 구조체를 지정해주면 된다.

package main

import (
  "fmt"
  "net/http"
)

type RessonseMessage string

func (s RessonseMessage) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  fmt.Fprint(w, s)
}
func main() {
  helloServer := RessonseMessage("hi. there")

  http.Handle("/", helloServer)
  http.ListenAndServe(":8000", nil)
}

 



Handle

 

2.경로에 따라서 다르게 응답하는 서버  

net/http로 요청에 응답을 하는 방식은 HandleFunc  또는  Handle 함수에 두번쨰 인자로 함수를 건네주면된다.

함수를  인터페이스 형식으로 건네주고 싶을 때는 type을 사용한다.
https://github.com/sugoigroup/study_golang/tree/http

type fooHandler struct{}


func Runserver() {


     mux := http.NewServeMux()

     mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        fmt.Fprint(w, "Hello World")

     })


     mux.Handle("/foo", &fooHandler{})


     http.ListenAndServe(":3000", mux)


}


func (f *fooHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

  fmt.Fprint(w, strutils.ToUpperCase("Hello Foo!"))

}

3.url 에 입력된 파라메터를 읽기  

보통 url에 파라메터를 붙여 서버에 어떤 값을 전송한다. 간단히 url query에서 값을 가져와보자. 간단하다.

func Runserver() {

     mux := http.NewServeMux()

     mux.HandleFunc("/bar", barHandler)

     http.ListenAndServe(":3000", mux)

}


func barHandler(w http.ResponseWriter, r *http.Request) {

  name := r.URL.Query().Get("name")

  if name == "" {

     name = "world"

  }

  fmt.Fprintf(w, "Hello %s!", name)

}

4.응답을  html 로 하기   

보통 url에 파라메터를 붙여 서버에 어떤 값을 전송한다. 간단히 url query에서 값을 가져와보자. 간단하다.

func Runserver() {


     mux := http.NewServeMux()

     mux.HandleFunc("/bar", barHandler)

     http.ListenAndServe(":3000", mux)


}


func barHandler(w http.ResponseWriter, r *http.Request) {

  name := r.URL.Query().Get("name")

  if name == "" {

     name = "world"

  }

  w.Header().Set("Content-Type", "text/html") // HTML 헤더 설정

  w.Write(htmlMessage(name))

}


func htmlMessage(msg string) []byte {

  // HTML로 웹 페이지 작성

  html := `

  <html>

  <head>

     <title>Hello</title>

  </head>

  <body>

     <div style='text-align:center'><b>Hello ` + msg + `</b></div>

  </body>

  </html>

  `

  return []byte(html)

}


0 comments:

댓글 쓰기