Golang 이 어떻게 동작하는지 정~말 간단히 알아봤다면 이제 간단한 web application을 구현해보자.
이번 시리즈에서는 아래와 같은 것들을 다룰것이다.

- 데이터 구조를 생성해서 조회하고 저장하기
- net/http 패키지를 이용해서 web application 빌드하기
- html/template을 이용해서 HTML 템플릿 생성하기
- regexp 패키지를 이용해서 사용자 검증하기


당연히, Go가 기본적으로 설치되어 있어야 한다. 혹시라도 안되어있다면 이전에 작성한 go 설치하기 편을 참고하자.

1. 설정한 GOPATH 위치로 이동해서 폴더를 생성한다.

$ mkdir gowiki
$ cd gowiki

 

2. wiki.go 라는 파일을 생성하고 아래 내용을 작성한다.
fmt와 ioutil 패키지를 go standard library에서 import 받는다.
추후 기능을 구현할때 사용할 패키지들이다.

package main

import (
	"fmt"
	"io/ioutil"
)

 

3. 이제 데이터 구조를 정의해보자. 우리가 구현할 wiki는 상호 연결된 페이지로 구성되며 각 페이지에는 제목과 본문이 있다.
제목과 본문으로 구성될 Page를 구성해보자.

- []byte 타입은 이전 시간에 배웠던 byte slice 다. Body 요소는 io 라이브러리에서 사용할 것이므로 문자열이 아니라 []byte 형으로 정의했다.

type Page struct {
    Title string
    Body  []byte
}

- Page 구조체는 어떻게 페이지 데이터가 메모리에 저장되는지에 대한 방법을 설명할 것이다. 만약 메모리에 올리는 것이 아닌 영구적으로 데이터를 저장해야 된다면?  아래의 save 메소드를 이용해서 해결 할 수 있다.
save 메소드는 Page에 대한 포인터를 가진 매서드이다. 이건 parameter는 없으며 error 값을 리턴한다.

func (p *Page) save() error {
    filename := p.Title + ".txt"
    return ioutil.WriteFile(filename, p.Body, 0600)
}

-이 메서드는 Page의 Body 부분을 text file로 저장하며, Title을 파일 이름으로 사용한다.
- WriteFile의 반환 유형에 따라 error를 리턴한다. 또한 파일을 쓰는 동안 문제가 발생하면 응용 프로그램에서 처리할 수 있도록 한다.만약 에러없이 끝난다면 Page.save() 메서드는 nil(포인터, 인터페이스 및 기타 유형의 경우 0) 값을 반환한다.
- WriteFile에 세번째 매개변수로 넘어가는 0600의 경우 현재 사용자에 대해서만 읽기-쓰기 권한으로 파일을 작성해야 함을 나타낸다.

추가로 page를 load 하는 함수를 추가해보자.

func loadPage(title string) *Page {
    filename := title + ".txt"
    body, _ := ioutil.ReadFile(filename)
    return &Page{Title: title, Body: body}
}

- loadPage 함수는 title 매개변수를 통해 파일이름을 생성하고 파일의 내용을 읽어들여 Page 리터럴에 대한 포인터를 반환한다.
- 해당 함수를 여러값을 반환하는데( []byte , error) 아직 우리는 에러처리를 하지 않았다.
- (_) 밑줄로 표한된 빈 식별자는 오류반환 값을 그냥 처리는데 사용된다. ( 아무처리도 하지 않음)
- 근데 만약 ReadFile에 오류가 발생하면 어떻게 될까? 예를 들어 없는 파일을 읽으려고 할 수도 있다.이런 오류를 처리하기 위한 처리를 추가해 보자.

func loadPage(title string) (*Page, error) {
    filename := title + ".txt"
    body, err := ioutil.ReadFile(filename)
    if err != nil {
        return nil, err
    }
    return &Page{Title: title, Body: body}, nil
}

- 이제 이 함수를 호출하는 곳에서는 두 번째 매개변수를 확인 할 수 있다.
만약 Page를 성공적으로 로드했으면 아무 일도 없을 것이고 중간에 에러가 발생하면 호출자는 에러를 처리할 수 있다.

- 이 시점에서 우리는 간단한 데이터 구조를 통해 파일로 저장하고 로드할 수 있다.
테스트 해보기 위해 main 메서드를 작성해보자.

func main() {
    p1 := &Page{Title: "TestPage", Body: []byte("This is a sample Page.")}
    p1.save()
    p2, _ := loadPage("TestPage")
    fmt.Println(string(p2.Body))
}

 

위와 같이 main 메서드를 작성하고 compile 후 코드를 실행하면 p1의 코드를 포함한 TestPage.txt 라는 파일이 만들어 질 것이고, P2를 통해 해당 txt를 읽어들여 Body 내용이 화면에 찍힐 것이다.
그럼 실습해보자!. 

$ go build wiki.go
$ ./wiki
This is a sample Page.

 

아래처럼 정상적으로 나온것을 확인 할 수 있다.

 

+ Recent posts