
golang 에서 서버를 만들려면 두 가지 함수가 필요하다.
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Welcome home!!")
})
log.Fatal(http.ListenAndServe(":3000", nil))
첫 번째는 http.HandleFunc() 으로 홈페이지 주소에 요청이 들어오면 다음 함수를 실행하겠다는 핸들러 함수다. 여기서 Fprinf 는 데이터를 콘솔에 출력하지 않고 ResponseWriter 에게 넘긴다.
두 번째는 http.ListenAndServe() 다. 포트와 핸들러를 받아서 서버를 구동하는데 공식 문서에 따르면 보통 핸들러는 nil로 넣어주고 함수에서 error를 리턴하기 때문에 log.Fatal()로 감싸준다.

log.Fatal(v ...interface{}) //에러 로그를 출력하고 프로그램을 완전히 종료
log.Panic(v ...interface{}) //시간과 에러 문자열을 출력한 뒤 패닉을 발생시킴
log.Print(v ...interface{}) //시간과 에러 메시지를 출력하며 프로그램을 종료하지 않음

log.Fatal의 설명을 보면 os.Exit(1) 다음에 오는 에러를 프린트하는 것과 같다고 나온다. 그럼 os.Exit(1)은 무엇일까?

공식 문서에 따르면 프로그램을 종료하도록 해주는 메소드라는 것을 알 수 있다. os.Exit(0) 은 성공적으로 프로그램을 종료하기 때문에 에러를 출력하지 않으며, 0을 제외한 나머지 숫자를 넣으면 에러와 함께 프로그램을 종료시킨다.
type Homedata struct {
PageTitle string
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
tmpl, err := template.ParseFiles("templates/home.html")
if err != nil {
log.Fatal(err)
}
data := Homedata{"Home"}
tmpl.Execute(w, data)
})
}
template 패키지의 ParseFiles 를 통해 html 파일을 가져온다. 이 때 error 를 같이 리턴하기 때문에 이를 통해 에러 체크를 해주면 된다.

그 다음 Execute 를 통해 parse 된 데이터를 writer에 넘겨주고

html에서 받아온 데이터를 표시해주면 끝
<body>
<h1>{{.PageTitle}}</h1>
</body>

추가적으로 template.Must() 를 사용하면 에러 체크를 하는 효과를 얻을 수 있다.
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
tmpl := template.Must(template.ParseFiles("templates/home.html"))
tmpl.Execute(w, data)
})

template에서 {{}} 를 사용해 field를 전달 받을 수 있다. 이 때 field 이름을 대문자로 해야 정상적으로 export 되는 것을 잊지 말자.

HTML 파일에서 반복문을 사용하려면 {{range}} {{end}} 를 사용하면 된다.
<body>
<h1>{{.PageTitle}}</h1>
{{range .Blocks}}
<div>
<ul>
<li>{{.Data}}</li>
<li>{{.Hash}}</li>
<li>{{.PrevHash}}</li>
</ul>
</div>
{{end}}
</body>