Go 를 이용한 간단한 웹 어플리케이션을 만들어보자. golang 은 이미 설치되어 있다고 가정한다. Go 설치 이전이라면 다음 포스팅을 참조한다.
http://redhotkorea.tistory.com/?id=1821
설치가 끝나면 go 디렉토리로 이동한다. go 디렉토리 아래에 bin 과 src 폴더를 만들고, src 폴더 아래에 welcome-app 폴더를 생성하자.
1 2 3  | ~/go/src# mkdir welcome-app ~/go/src# cd welcome-app ~/go/src/welcome-app#  | cs | 
다음과 같은 디렉토리 구조를 가지게 된다.
1 2 3 4 5 6 7  | /home   /<your-username>     /go       bin/          //Empty for now        src/         /welcome-app  | cs | 
구체적인 코딩에 앞서 프런트 엔드 셋업부터 진행하자. 대부분의 GO 어플리케이션에서는 html 코드는 보통 템플릿 폴더안에 위치해있다. 필수사항은 아니지만, 이런 식으로 구성하는 것이 도움이 된다.
~/go/src/welcome-app 아래에 html 이 위치할 템플릿 디렉토리를 생성한다.
~/go/src/welcome-app 아래에 css 가 위치할 static/stylesheets 디렉토리를 생성한다.
1 2 3 4 5 6 7 8 9  | ~/go/src/welcome-app# mkdir templates ~/go/src/welcome-app# mkdir -p static/stylesheets ~/go/src/welcome-app# tree . ├── static │   └── stylesheets └── templates 3 directories, 0 files  | cs | 
템플릿 디렉토리에 welcome-template.html 을 생성한다. 무표 이미지 사이트(https://www.pexels.com 나 https://www.pikwizard.com 등)에서 배경이미지로 활용할 이미지를 다운로드 받아 background 라고 이름을 붙인다. 그리고 static/stylesheets 디렉토리에 welcome-template.css 을 만든다.
1 2 3 4 5 6 7 8 9 10  | ~/go/src/welcome-app# tree . ├── static │   └── stylesheets │       └── welcome-template.css └── templates     └── welcome-template.html 3 directories, 2 files  | cs | 
HTML
아래 코드를 templates/welcome-template.html에 그대로 붙여넣는다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  | templates/welcome-template.html <!DOCTYPE html> <html>    <head>          <meta charset="UTF-8">          <link rel="stylesheet" href="/static/stylesheets/welcome-template.css">          <!-- The welcome struct (shown in the main.go code) is received within the HTML and we just need to use the . operator and retrieve the information we want -->          <title>Welcome {{.Name}}</title>    </head>    <body>       <div class="welcome center">Welcome {{.Name}}, it is {{.Time}}</div>    </body> </html>  | cs | 
CSS
마찬가지로 static/stylesheets/welcome-template.css 파일에 다음 내용을 복사한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  | body  {    min-height:100%;    background-image: url("/static/stylesheets/background.jpg"), linear-gradient(rgba(0,0,0,0.2),rgba(0,0,0,0.3));    background-blend-mode: overlay;    background-size:cover } .welcome {    font-family: 'Segoe UI', 'Tahoma', 'Geneva', 'Verdana', 'sans-serif';    font-size: 3rem;    color: aliceblue; } .center {    height: 100vh;     display: flex;     justify-content: center;     align-items: center }  | cs | 
배경이미지
위의 css 에 나와있는대로 /static/stylesheets/ 폴더 아래에 background.jpg 라는 이름으로 저장한다.
현재까지의 디렉토리 구조는 다음과 같다.
1 2 3 4 5 6 7 8 9 10  | ~/go/src/welcome-app# tree . ├── static │   └── stylesheets │       ├── background.jpg │       └── welcome-template.css └── templates     └── welcome-template.html 3 directories, 3 files  | cs | 
그러면, 서버 구축을 위한 몇 가지 로직에 대해 알아보자.
1. 먼저 4개의 중요한 라이브러리를 임포트한다.
1 2 3 4 5 6 7 8  | package main import (    "net/http"    "fmt"    "time"    "html/template" )  | cs | 
1) “net/http” 은 핵심 go http 기능에 억세스하기 위한 것이다.
2) “fmt” 은 텍스트 포맷용도
3) “html/template” 은 html 파일과 상호작용하기 위한 라이브러리이다.
4) "time" 은 date 와 time 을 다루는 라이브러리이다.
2. 다음으로 HTML 에 표시될 정보를 담고 있는 구조체(struct)를 만든다.
1 2 3 4  | type Welcome struct {    Name string    Time string }  | cs | 
3. Go 어플리케이션 진입 포인트
Welcome 구조체 객체를 Instantiate 후 랜덤한 정보를 넣는다.
1 2  | func main() {    welcome := Welcome{"Anonymous", time.Now().Format(time.Stamp)}  | cs | 
Go 에게 html 경로를 알려준다. 그리고 에러 처리나 심각한 오류가 있을 때 멈출 수 있도록 template.Must() 에 싸서 넣는다.
1  |   templates := template.Must(template.ParseFiles("templates/welcome-template.html"))  | cs | 
다음으로 go 에게 static 디렉토리를 검색하는 핸들을 생성하게 한다. 그러면 go 는 /static/ 을 html 이 css 와 기타 파일을 검색할 때 참고하는 url 로 사용하게 될 것이다. Go 는 먼저 http.FileServer() 를 통해 상대적인 "static" 디렉토리를 찾는다. 그리고 http.Handle("/static/") 에서 보여주는 url 과 매칭한다. 이 url 은 css 파일을 참고할 때도 필요하다.
1 2 3  |  http.Handle("/static/", //final url can be anything       http.StripPrefix("/static/",          http.FileServer(http.Dir("static"))))  | cs | 
이 메서드는 "/" 라는 URL 경로와response writer 와 http request 를 포함하는 함수를 가진다.
1  |  http.HandleFunc("/" , func(w http.ResponseWriter, r *http.Request) {  | cs | 
URL 쿼리에서 이름을가져온다. 예를 들어, s?name=Martints 의 경우, welcome.name = Martin 이 되는 것이다.
1 2 3  |  if name := r.FormValue("name"); name != "" {          welcome.Name = name;       }  | cs | 
Internal Server Error 메시지를 보여주는 경우, welcome 구조체를 welcome-template.html 파일로 전달한다.
1 2 3 4  |  if err := templates.ExecuteTemplate(w, "welcome-template.html", welcome); err != nil {          http.Error(w, err.Error(), http.StatusInternalServerError)       }    })  | cs | 
웹서버를 시작하고, 포트를 8080 으로 설정한다. path 가 없는 경우 localhost 로 간주한다. fmt 를 이용하여 웹서버 시동과 관련한 에러를 출력한다.
1 2 3  |    fmt.Println("Listening");    fmt.Println(http.ListenAndServe(":8080", nil)); }  | cs | 
주석이 달리지 않은 전체 코드는 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38  | package main import (    "net/http"    "fmt"    "time"    "html/template" ) type Welcome struct {    Name string    Time string } func main() {    welcome := Welcome{"Anonymous", time.Now().Format(time.Stamp)}    templates := template.Must(template.ParseFiles("templates/welcome-template.html"))    http.Handle("/static/",        http.StripPrefix("/static/",          http.FileServer(http.Dir("static"))))     http.HandleFunc("/" , func(w http.ResponseWriter, r *http.Request) {       if name := r.FormValue("name"); name != "" {          welcome.Name = name;       }       if err := templates.ExecuteTemplate(w, "welcome-template.html", welcome); err != nil {          http.Error(w, err.Error(), http.StatusInternalServerError)       }    })    fmt.Println("Listening");    fmt.Println(http.ListenAndServe(":8080", nil)); }  | cs | 
어플리케이션을 구동해보자.
1 2 3 4  | :~/go/src/welcome-app# go run main.go Listening   | cs | 
포트 8080에서 서버를 구동하게 된다. localhost:8080 와 같은 형식으로 웹브라우저에서 실행하면 된다. 이름을 출력하고 싶은 경우 localhost:8080/?name=alex 와 같이 실행한다.
완성된 모습이다.
'Season 1 아카이브 > 프로그래밍' 카테고리의 다른 글
| 구글 클라우드 플랫폼 도메인 네임 설정하기 How to Transfer Domain Names to Google Cloud Hosting (0) | 2018.11.06 | 
|---|---|
| SSH를 이용한 구글 클라우드 플랫폼 VM 접속하기 - PuTTY 부터 FileZilla 까지 (0) | 2018.10.23 | 
| SQLTools connect - cannot save "connections.xml" error (0) | 2018.09.17 | 
| Go 언어 입문 - Control Structures - Functions (2) (golang-book) (0) | 2018.09.09 | 
| Go 언어 입문 - Control Structures - Functions (1) (golang-book) (0) | 2018.09.09 |