/main.go
package main
type User struct {
Name string `json:"name"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
func getUserInfoHandler(w http.ResponseWriter, r *http.Request) {
user := User{Name: "yklovejesus", Email: "yklovejesus@gmail.com"}
w.Header().Add("Content-type", "application/json")
w.WriteHeader(http.StatusOK)
data, _ := json.Marshal(user)
fmt.Fprint(wm string(data))
}
func addUserHandler(w http.ResponseWriter, r *http.Request) {
user := new(User)
err := json.NewDecoder(r.Body).Decode(user)
if err != nil {
rd.Text(w, http.StatusBadRequest, err.Error())
return
}
user.CreatedAt = time.Now()
w.Header().Add("Content-type", "application/json")
w.WriteHeader(http.StatusOK)
data, _ := json.Marshal(user)
fmt.Fprint(wm string(data)
}
func helloHandler(w http.ResponseWriter, r *http.Request) { // 2
tmpl, err := template.new("Hello").ParseFiles("templates/hello.tmpl")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprint(w, err)
return
}
tmpl.ExecuteTemplate(w, "hello.tmpl", "changbeom")
}
func main() {
mux := pat.New()
mux.Get("/users", getUserInfoHandler) // 1
mux.Post("/users", addUserHandler)
mux.Get("/hello", helloHandler)
http.ListenAndServe(":3000", mux)
Go
복사
•
이번에는 gorilla mux가 아닌 gorilla pat을 사용할 예정
•
좀 더 심플한 라우터라고 생각하면 된다.
•
설치 명령어
go get github.com/gorilla/pat
Go
복사
•
기존 gorilla mux를 사용하여 GET,POST를 했을 때 쓰는 방식이 조금 다른 것을 확인 할 수 있다.
•
지난번에 했던 템플릿을 사용해보려 한다.
•
코드 구조들은 지난번에 했었던 RESTful API와 비슷한 것을 확인 할 수 있다.
/templates/hello.html
<html>
<head>
<title>Hello Go in Web</title>
</head>
<body>
Hello World{{.}}
</body>
</html>
HTML
복사
이제 동작을 확인해보기 위해 클라이언트 앱으로 동작시켜보자!
GET
POST
Hello
•
이렇게 결과를 확인 할 수 있다.
•
이제 매번 JSON을 쓰고, 템플릿을 전하는게 귀찮기 때문에 간단하게 해주는 render 패키지를 추가한다.
•
설치 방법
github.com/unrolled/render
Plain Text
복사
•
사용법은 간단하다. 먼저 전역변수인 rd를 추가해준다.
var rd *render.Render
Go
복사
•
이렇게 하면 render의 패키지가 import하게 된다.
•
그 다음 main.go에서 인스턴스를 만든뒤 코드를 수정해준다.
func getUserInfoHandler(w http.ResponseWriter, r *http.Request) {
user := User{Name: "tucker", Email: "tucker@naver.com"}
rd.JSON(w, http.StatusOK, user) // 1
}
func addUserHandler(w http.ResponseWriter, r *http.Request) {
user := new(User)
err := json.NewDecoder(r.Body).Decode(user)
if err != nil {
rd.Text(w, http.StatusBadRequest, err.Error())
return
}
user.CreatedAt = time.Now()
rd.JSON(w, http.StatusOK, user)
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
rd.HTML(w, http.StatusOK, "hello", "Tucker") // 2
}
func main() {
rd = render.New() // 2
mux := pat.New()
mux.Get("/users", getUserInfoHandler)
mux.Post("/users", addUserHandler)
mux.Get("/hello", helloHandler)
http.ListenAndServe(":3000", n)
}
Go
복사
•
첫번째 인자가 ResponseWriter, 두번째 인자가 status, 세번째 인자가 JSON으로 바꾸고싶은 인스턴스이다. 이 한줄로 끝이 난다.
•
첫번째 인자가 ResponseWriter, 두번째 인자가 status, 세번째 인자가 템플릿 파일, 네번째 인자가 템플릿에 넣을 인스턴스 값이다.
GET
POST
HELLO
•
그리고 Hello 템플릿에서 .tmpl외에도 .HTML이 될 수 있는데 이 때 템플릿을 .HTML로 변경하면 클라이언트 앱에서 읽어오지 못한다.
•
HTML도 읽어 줄 수 있게 하기 위해 Main 부분을 수정해준다.
func main() {
rd = render.New(render.Options{
Directory: "template",
Extensions: []string{".html", ".tmpl"},
})
mux := pat.New()
mux.Get("/users", getUserInfoHandler)
mux.Post("/users", addUserHandler)
mux.Get("/hello", helloHandler)
http.ListenAndServe(":3000", n)
}
Go
복사
•
Extensions이라는 옵션이 있는데 템플릿을 읽어올 때 어떤 확장자를 읽을지 알려주는 옵션이다.마찬가지로 디렉토리가 바뀔 수 있는데, 어떤 디렉토리를 읽고자 하는지 사용하는 옵션이다.
•
이번에는 템플릿에 어떤 레이아웃을 추가하는 것을 해보고자한다.저번 시간에 템플릿을 기능에 따라 2개 나누었듯이 나눠보자!
template/body.html
Name: {{.Name}}
Email : {{.Email}}
HTML
복사
•
# template/hello.HTML를 body를 넣을 부분을 수정해주자!
<html>
<head>
<title>Hello Go in Web</title>
</head>
<body>
Hello World
{{ yield }}
</body>
</html>
HTML
복사
•
Main 부분을 수정해준다.
func helloHandler(w http.ResponseWriter, r *http.Request) {
user := User{Name: "tucker", Email: "tucker@naver.com"} // 1
rd.HTML(w, http.StatusOK, "body", user)
}
func main() {
rd = render.New(render.Options{
Directory: "template",
Extensions: []string{".html", ".tmpl"},
Layout: "hello",
})
mux := pat.New()
mux.Get("/users", getUserInfoHandler)
mux.Post("/users", addUserHandler)
mux.Get("/hello", helloHandler)
http.ListenAndServe(":3000", n)
}
Go
복사
•
body 템플릿에 넣어주기 위해 수정
•
이 상태에서 실행
•
정상적으로 작동 되는 것을 확인
•
body는 {{ yield }}로 템플릿을 지정했지만 title부분도 템플릿으로 지정해주고 싶다면 이렇게 수정해주면 된다.
<html>
<head>
<title>{{ partial "title" }}</title>
</head>
<body>
Hello World
{{ yield }}
</body>
</html>
HTML
복사
•
이렇게 만들어 준 뒤 title에 해당하는 템플릿을 만들면 된다!template/title-body.html
Partial Go in Web
Plain Text
복사
•
title-body라고 이름을 만들면 layout에서 해당 title에 해당하는 이름과 main.go의 body값을 읽은 부분을 채워주게 된다.
•
마지막으로 설치해볼 패키지는 negroni라는 패키지인데 HTTP 미들웨어이다.기본적으로 많이 쓰이는 부가기능들을 제공하는 패키지 라고 생각하면 된다.
go get github.com/urfave/negroni
Plain Text
복사
•
main.go를 수정하기 앞서 public 폴더에 index.html을 생성한다.
<html>
<head>
<title>Go in Web 11</title>
</head>
<body>
<h1>Hello Go in Web</h1>
</body>
</html>
HTML
복사
•
기본적인 것을 사용할 때는 간단
func main() {
rd = render.New(render.Options{
Directory: "template",
Extensions: []string{".html", ".tmpl"},
Layout: "hello",
})
mux := pat.New()
mux.Get("/users", getUserInfoHandler)
mux.Post("/users", addUserHandler)
mux.Get("/hello", helloHandler)
n := negroni.Classic() // 1
n.UseHandler(mux) // 2
http.ListenAndServe(":3000", n) // 3
}
Go
복사
•
이걸 사용하면 핸들러가 하나 나온다.
•
mux를 매핑해서 부가기능들을 추가해준다.3 : 핸들러의 n을 추가
•
그러면 n이 가지고 있는것이 기본 파일 서버를 가지고 있고, log를 찍는 기능을 제공하고 있다.실행해보면정상적으로 화면이 나오며
•
터미널창에 log가 찍힌 것을 확인
소스코드 전부
main.go
package main
import (
"encoding/json"
"net/http"
"time"
"github.com/gorilla/pat"
"github.com/unrolled/render"
"github.com/urfave/negroni"
)
var rd *render.Render
type User struct {
Name string `json:"name"`
Email string `json:"email"`
CreatedAt time.Time `json:"created_at"`
}
func getUserInfoHandler(w http.ResponseWriter, r *http.Request) {
user := User{Name: "tucker", Email: "tucker@naver.com"}
rd.JSON(w, http.StatusOK, user)
}
func addUserHandler(w http.ResponseWriter, r *http.Request) {
user := new(User)
err := json.NewDecoder(r.Body).Decode(user)
if err != nil {
rd.Text(w, http.StatusBadRequest, err.Error())
return
}
user.CreatedAt = time.Now()
rd.JSON(w, http.StatusOK, user)
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
user := User{Name: "tucker", Email: "tucker@naver.com"}
rd.HTML(w, http.StatusOK, "body", user)
}
func main() {
rd = render.New(render.Options{
Directory: "template",
Extensions: []string{".html", ".tmpl"},
Layout: "hello",
})
mux := pat.New()
mux.Get("/users", getUserInfoHandler)
mux.Post("/users", addUserHandler)
mux.Get("/hello", helloHandler)
n := negroni.Classic()
n.UseHandler(mux)
http.ListenAndServe(":3000", n)
}
Go
복사
template/body.html
Name: {{.Name}}
Email: {{.Email}}
HTML
복사
template/hello.html
<html>
<head>
<title>{{ partial "title" }}</title>
</head>
<body>
Hello World
{{ yield }}
</body>
</html>
HTML
복사
template/title-body.html
Partial Go in Web
HTML
복사
public/index.html
<html>
<head>
<title>Go in Web 11</title>
</head>
<body>
<h1>Hello Go in Web</h1>
</body>
</html>
HTML
복사