Go 언어

본문 바로가기
사이트 내 전체검색


Go 언어
Go 언어

1. 웹서버 만들기(1)

페이지 정보

작성자 관리자 댓글 0건 조회 1,749회 작성일 21-07-04 20:39

본문

1. 웹서버 만들기(1)

1. Handler 다뤄보기


WEB1 폴더에 작성했다. 


파일명 : main.go


package main


import (

"net/http"

"fmt"

)

func main() {

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

fmt.Fprint(w, "Hello World")

})


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

fmt.Fprint(w, "Hello Bar!")

})


http.ListenAndServe(":3000", nil)

}


실행하기


C:\Users\jklee>d:

D:\>cd goapp 

D:\GoApp>cd web1 

D:\GoApp\web1>go run main.go


1.PNG


2.PNG


3.PNG




HandleFunc : 어떤 request가 들어왔을 때 어떤 일을 할 것인지 핸들러를 등록하는 함수 

/ -> 첫 번째 인덱스 페이지를 나타낸다.

w : Response를 write할 수 있는 인자

r : 사용자가 요청한 Request정보를 가지고 있는 인자

fmt.Fprint(w, "Hello World") : Hello World라는 response를 줘라

ListenAndServe : 웹 서버가 구동되고 Request를 기다리는 상태가 됨(3000포트에서 기다림)


주소에 http://localhost:3000라고 치면 첫 번째 핸들러가 돌아가고


주소에 http://localhost:3000/bar라고 치면 두 번째 핸들러가 돌아간다.


즉 경로에 맞는 핸들러가 돌아간다.




2. 핸들러의 다양한 방법


파일명 : main.go


package main


import (

"net/http"

"fmt"

)

type fooHandler struct{}


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

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

}


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

fmt.Fprint(w, "Hello Bar!")

}


func main() {

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // 루트 주소

fmt.Fprint(w, "Hello World")

})


http.HandleFunc("/bar", barHandler)


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


http.ListenAndServe(":3000", nil)

}


같은 방법으로 실행한다.


4.PNG


HandleFunc : 함수를 직접 등록

Handle : 인스턴스 형태로 등록(인스턴스를 만들고 거기에 해당하는 인터페이스를 구현)


여기까지는 http에 정적으로 등록했다.


새로운 라우터 인스턴스를 만들어서 그 인스턴스를 넘겨주는 방식으로 구현해 보겠다.


파일명 : main.go


package main


import (

"net/http"

"fmt"

)


type fooHandler struct{}


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

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

}


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

fmt.Fprint(w, "Hello Bar!")

}


func main() {

mux := http.NewServeMux()

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

fmt.Fprint(w, "Hello World")

})


mux.HandleFunc("/bar", barHandler)

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

http.ListenAndServe(":3000", mux) 

}


같은 방법으로 실행한다.

같은 결과를 확인할 수 있다.


request에서 input값을 뽑아보는 방식으로 구현해 보겠다.

request에 필요한 argument(input)값을 넣을 수 있다. 


파일명 : main.go


package main


import (

"net/http"

"fmt"

)


type fooHandler struct{}


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

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

}


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

// URL에서 argument를 뽑아냄

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

if name == "" {

name = "world"

}

fmt.Fprintf(w, "Hello %s!", name) // 그 값을 출력

}


func main() {

mux := http.NewServeMux()

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

fmt.Fprint(w, "Hello World")

})


mux.HandleFunc("/bar", barHandler)

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

http.ListenAndServe(":3000", mux)

}



차이점을 비교해 본다. 


5.PNG


6.PNG





3. JSON 다뤄보기



web browger가 request를 보낼 때 request에 JSON형태의 데이터를 보내고 server가 다시 JSON형태의 데이터를 response해주는 코드이다.


파일명 : main.go


package main


import (

"net/http"

"fmt"

"time"

"encoding/json"

)

type User struct {

FirstName string

LastName  string

Email     string

CreatedAt time.Time

}

type fooHandler struct{}


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

user := new(User)

err := json.NewDecoder(r.Body).Decode(user) 

// NewDecoder는 io.Reader를 인자로 받고 Body는 io.Reader를 포함하고 있다.

if err != nil {

w.WriteHeader(http.StatusBadRequest) 

// hear로 오류가 있다는 것을 알려줌

fmt.Fprint(w, "Bad Request: ", err)  

// body에 에러를 알려줌

return

}


user.CreatedAt = time.Now()

data, _ := json.Marshal(user) 

// 인터페이스를 받아서 json형태로 바꿔주는 메소드(byte와 err를 리턴함)

w.WriteHeader(http.StatusCreated)

fmt.Fprint(w, string(data))

}


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

// URL에서 argument를 뽑아냄

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

if name == "" {

name = "world"

}

fmt.Fprintf(w, "Hello %s!", name) // 그 값을 출력

}


func main() {

mux := http.NewServeMux()

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

fmt.Fprint(w, "Hello World")

})


mux.HandleFunc("/bar", barHandler)

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

http.ListenAndServe(":3000", mux)

}


같은 방법으로 다음과 같이 실행한다.


D:\GoApp\web1>go run main.go 


7.PNG


?name=leelab 은 url에 데이터를 넣는 것이기때문에 안되고 body에 넣어야한다.


http client app설치 후 확인해본다.


https://install.advancedrestclient.com/install 




11.PNG


다운받아 설치하고 실행한다. 


BODY를 선택하고 아래 내용을 입력한다.


{

  "first_name":"Jinkwan",

"last_name":"Lee",

"email":"leejinkwan@kunsan.ac.kr"

}


12.PNG



firstname과 lastname에 값이 없는 이유는 json에서 쓰는 방식하고 go에서 쓰는 방식이 다르기 때문이다. 따라서 맞춰줘야한다.


type User struct {

FirstName string `json:"first_name"`

LastName  string `json:"last_name"`

Email     string `json:"email"`

CreatedAt time.Time `json:"created_at"`

}


User struct를 수정한다.


annotation을 사용하여 설명을 붙여준다.

json에서는 이렇게 쓰인다 라는 의미이다.


다시 웹프로그램을 실행하고, 확인한다.


13.PNG









잘 들어간 것을 확인할 수 있다.


하지만 JSON포멧으로 나오는 것이 아니라 한 줄로 나온다. 그 이유는 웹이 보았을 때 content-type을 text로 인식하기 때문이다.

따라서 JSON이라고 알려줘야한다.


w.WriteHeader(http.StatusCreated)위에 아래 해더파일설정을 추가한다.


w.Header().Add("content-type", "application/json")



정상적인 형태로 잘 나온것을 확인할 수 있다. 


14.PNG

 


-----------------------------------------------------------------------

전체 소스 :

package main

import (
"net/http"
"fmt"
"time"
"encoding/json"
)
type User struct {
FirstName string `json:"first_name"`
LastName  string `json:"last_name"`
Email     string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
type fooHandler struct{}

func (f *fooHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
user := new(User)
err := json.NewDecoder(r.Body).Decode(user) 
// NewDecoder는 io.Reader를 인자로 받고 Body는 io.Reader를 포함하고 있다.
if err != nil {
w.WriteHeader(http.StatusBadRequest) 
// hear로 오류가 있다는 것을 알려줌
fmt.Fprint(w, "Bad Request: ", err)  
// body에 에러를 알려줌
return
}

user.CreatedAt = time.Now()
data, _ := json.Marshal(user) 
// 인터페이스를 받아서 json형태로 바꿔주는 메소드(byte와 err를 리턴함)
w.Header().Add("content-type", "application/json")
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, string(data))
}

func barHandler(w http.ResponseWriter, r *http.Request) {
// URL에서 argument를 뽑아냄
name := r.URL.Query().Get("name")
if name == "" {
name = "world"
}
fmt.Fprintf(w, "Hello %s!", name) // 그 값을 출력
}

func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello World")
})

mux.HandleFunc("/bar", barHandler)
mux.Handle("/foo", &fooHandler{})
http.ListenAndServe(":3000", mux)
}


댓글목록

등록된 댓글이 없습니다.


개인정보취급방침 서비스이용약관 모바일 버전으로 보기 상단으로

TEL. 063-469-4551 FAX. 063-469-4560 전북 군산시 대학로 558
군산대학교 컴퓨터정보공학과

Copyright © www.leelab.co.kr. All rights reserved.