[Go] Go 언어 웹 개발 프로젝트 Part1 - 프로젝트별 설정 및 commit git 진행 전 -

입문


안녕하세요.최근에는 Rails 이외의 언어를 더 이상 접하지 않고 있으며, 향후 가능성으로 Go 언어로 웹 개발을 진행할 수 있기 때문에 이번에 Go가 데뷔하여 그 증거를 남기게 되었습니다.Go에 대한 지식이 거의 없기 때문에 우선 자료를 수집해야 한다.그럼 가보자.

왜 Go 언어를 선택했습니까?


한 친구의 말에 의하면 Go언어는 학습 비용이 낮기 때문에 이전에 Rails에서 개발한 프로젝트를 Go언어로 바꾸었다고 한다.우선 Go언어의 학습 원가가 낮든 낮든 간에 제가 흥미를 느끼는 것은 사실입니다. 실제로 Go언어를 강력히 추천하는 증거를 찾아보았더니 다음과 같은 보도를 발견했습니다.
Why should you learn Go?
총계 정도
* ハードウェアの進歩は年々向上しているが、シングルスレッドのパフォーマンスとプロセッサの周波数は頭打ちになってきた
* 上の問題を解決するために、プロセッサにキャッシュの追加やハイパースレッディング、コアを増やすと言った解決法を行ってきたが物理的な限界はくるし、コストもかかる
* したがってハードウェア以外の観点からパフォーマンスを向上させるためにソフトウェアでパフォーマンスを向上させる
* 現代のプログラミング言語(Java, Pythonなど)は最初はシングルスレッドでの開発のみを想定していた
* Go言語は初めからマルチスレッドによる開発を想定して実装されている
* Goはスレッドの代わりにGoルーチンを採用している
* GoはJava,Pythonと言った高級言語とC,C++と言った低水準言語の良い所取りだ
* Go言語はクラスや継承、例外などをサポートしていない
영어는 공부하고 있지만 왠지 이해할 수 있을 것 같아요.나는 이렇게 학습 원가가 낮아도 믿을 만하지 않다고 기사를 읽었지만 처음부터 성능을 고려하여 설계한 언어는 확실히 매력적인 언어였다.이렇게 하면 Go 언어를 배울 수 있는 동력이 생기니 실제로 개발하자.

설치 Go


먼저 자신의 환경에 Go를 설치하는 것부터 시작합니다.최근 전 세계 설치 언어를 포기하고 rbenvpyenv 같은 프로젝트 저장소의 프로그램 언어 버전을 관리할 수 있는 도구를 사용하여 설치했습니다.
Go에도 이런 게 있나요?그래서 알아봤는데 금방 나왔어요.
https://github.com/syndbg/goenv
이 goenv를 사용하여 Go를 설치합니다.
% mkdir dairy_report
% cd dairy_report
% goenv install 1.11.0
% goenv local 1.11.0
PATH의 환경 변수에 goenv의 디렉터리를 지정하여 goenv에 설치된 Go를 실행합니다.
.zshrc
export PATH="$HOME/.rbenv/bin:$PATH" # rbenv                                
export PATH="$HOME/.pyenv/bin:$PATH" # pyenv                                
export PATH="$HOME/.goenv/shims:$PATH" # goenv                              
export RBENV_ROOT="$HOME/.rbenv"                                            
eval "$(rbenv init -)"                                                      
eval "$(pyenv init -)"                                                      
eval "$(goenv init -)
또한 Go에서는 개발 시 작업 디렉토리로서GOPATH의 환경 변수로 지정된 디렉토리를 지정해야 합니다.
이 GOPATH 아래의 디렉토리에 필요한 패키지 그룹이 설치됩니다.이번에는 프로젝트마다 GOPATH를 분리하기 위해 direnv 필요한 환경 변수를 프로젝트 특유의 것으로 읽는다.
direnv에 관해서→https://github.com/zimbatm/direnv
% brew install direnv
.zshrc
EDITOR=vim
eval "$(direnv hook zsh)"
디렉터리 바로 아래에 .envrc 스크립트 파일을 만듭니다.direnv를 가져오면 프로젝트 특유의 설정을 할 수 있습니다.
우선, 이거.envrc에만 GOPATH를 지정해 주세요.direnv edit ..envrc를 만들 수 있지만, 이 이벤트 EDITOR 전에 환경 변수가 지정한 편집기를 실행해야 합니다.환경 변수를 좌우로 편집하려고 하기 때문에vim로 설정합니다.여기 있는vendor의 지정은 후술한gom의 가방을 통일적으로 관리하는 도구로 설치된 가방의 위치를 통일시키기 위해 미리 같은 설정을 합니다.마지막으로 bin을 PATH로 지정하기 위해 PATH의 지정에 GOBIN의 정의를 추가합니다.
.envrc
export GOPATH="$(pwd)/vendor/"                                              
export GOBIN="$(pwd)/vendor/bin" 
export PATH="$GOBIN:$PATH"
위에서 저장하면loading을 할 수 있습니다.
direnv: loading .envrc                                                          
direnv: export +GOPATH
% echo $GOPATH
~/Desktop/Develop/dairy_report/go:

입문 강좌


공식 사이트의 강좌에 대략적인 일이 쓰여 있다.이것을 참고하여 코드를 쓰고 싶습니다.
https://tour.golang.org/welcome/1

Go 언어 기반 웹 개발


Go 언어로 웹 개발을 하는 의례적인 부분이 궁금해서 아래 슬라이드를 참고했습니다.
작가님이 Rubyist이기 때문에 제 상황에서도 어울릴 수 있을 것 같아서 참고 가치가 있습니다.
Go 웹 애플리케이션 개발 휴대폰

프레임 정보


그러면 Go 언어로 웹 개발을 진행해야 합니다. 그 전에 Go에서 사용하는 주류 프레임워크가 무엇인지 조사했습니다(상기 슬라이드에는 아직 표준이 없습니다).
그 중에서 아래의 블로그를 발견하였다.
Why I Don’t Use Go Web Frameworks
요약하면 이런 느낌이에요.
* Go言語自体がすでにWebフレームワーク化している。
* 多くのGo言語のフレームワークはHTTPリクエストとレスポンスを隠して抽象化したメソッドを提供している。
* しかし、それはわざわざ単純にできることをパフォーマンスを低下させてまでやっているのではないか
신경 쓰이는 게 위의 세 마디야?중요한 것은 Go언어는 원래net/http의 표준 라이브러리로 대체적으로 완성할 수 있기 때문에 일부러 프레임워크를 사용할 필요가 없다.그래서 정말 그랬는지 검증하고 싶어요.

일단 넷/http로 웹 서버를 써보도록 하겠습니다.


Go 프로그램은 packages로 구성됩니다.프로그램을 main 패키지에서 시작하기 위해 다음 프로그램이 실행될 때 8080번 포트에서 대기하는 서버 프로그램을 써 보았습니다.
main.go
package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/",
        func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintln(w, "Hello, World!")
            log.Printf("%+v¥n", r)
        })
    http.ListenAndServe(":8080", nil)
}
위에서 말한 바와 같이 방문http://0.0.0.0:8080은 다음과 같은 결과를 얻을 수 있다.

여기서부터 gorigori 코드를 쓰기 시작하여 그 전에 쉽게 개발할 수 있도록 각자의 환경을 조정합니다.

패키지 관리자


오랫동안 Rails와 친했기 때문에 이번에는 gom 포장 매니저를 채용했습니다.
방금 goenv와direnv의 GOPATH는 프로젝트 산하의 디렉터리에 설치하고 싶어서 다음 명령으로 gom를 얻었습니다.
% goenv exec go get github.com/mattn/gom
Bundler와 Gemfile처럼 사용하기 때문에 사용하기로 했습니다.

옮기다


DB의 버전 관리를 위해 goose 를 마이그레이션 도구로 사용하기로 결정했습니다.
Gomfile에서 통합적으로 관리할 수 있도록 Gomfile에서 추적하기로 했습니다.
Gomfile
gom bitbucket.org/liamstask/goose
gom을 통해 추가된 Goose 패키지를 설치할 수 있습니다.
이번에는 gom을 통해 설치되었기 때문에 앞에서 지정한 PATH의 지정에 따라 bin 산하의 gom를 호출할 수 있기 때문에 gom만 실행하면 됩니다.
% gom install
downloading bitbucket.org/liamstask/goose
# bitbucket.org/liamstask/goose/db-sample/migrations
runtime.main_main·f: function main is undeclared in the main package
gom:  exit status 2
이상이 끝났습니다. 이제 goose를 설치할 수 있습니다.
% goose
goose is a database migration management system for Go projects.

Usage:
    goose [options] <subcommand> [subcommand options]

Options:
  -env string
        which DB environment to use (default "development")
  -path string
        folder containing db info (default "db")
  -pgschema string
        which postgres-schema to migrate (default = none)

Commands:
    up         Migrate the DB to the most recent version available
    down       Roll back the version by 1
    redo       Re-run the latest migration
    status     dump the migration status for the current DB
    create     Create the scaffolding for a new migration
    dbversion  Print the current version of the database

Commit


여기서부터 드디어 진행하게 되었지만 길어질 것 같아서 잠시 제출하기로 했습니다.
.gitignore는 다음과 같은 설정을 했습니다.
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

*vendor/
*.idea
*.envrc
% git add . 
% git commit -m "first commit"
[master 72e578c] first commit
 4 files changed, 34 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 .go-version
 create mode 100644 Gomfile
 create mode 100644 main.go
% git push origin master
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 812 bytes | 812.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:himrock922/dairy_report.git
   bfb5b01..72e578c  master -> master

총결산


이번에는 사전 준비만 하고 깊은 곳에 가지 못했어요. 다음에는 코드를 쓰고 싶어요.
오늘은 잠시 여기까지 하겠습니다.

보충하여 기록하다

% gom install
downloading bitbucket.org/liamstask/goose
# bitbucket.org/liamstask/goose/db-sample/migrations
runtime.main_main·f: function main is undeclared in the main package
gom:  exit status 2
나는 이 문제의 원인을 이해했다.go get 원격 저장소에서 원본 코드를 가져와build를 실행합니다.
이build에서 이전 예시 파일 디렉터리에main 함수가 없는 Go 프로그램이 없어서 오류가 발생했습니다.
빌드 때 이 디렉터리를 배제할 수 없습니까?어쨌든 잘못된 행동이기 때문에 나중에 issue를 보고하겠습니다.

재추기


미안합니다.나는 goget 디렉터리의 지정된 경로를 잘 읽지 못했다.
https://bitbucket.org/liamstask/goose/src/master/
Install
$ go get bitbucket.org/liamstask/goose/cmd/goose
This will install the goose binary to your $GOPATH/bin directory.
따라서 cmd만 있는 바이너리 파일을 설치하기 위해 Gomfile을 고쳐야 합니다.
Gomfile
gom 'bitbucket.org/liamstask/goose/cmd/goose'
% gom install
downloading bitbucket.org/liamstask/goose/cmd/goose
이렇게 하면 goose를 정확하게 설치할 수 있다.

참고 문헌

  • https://tour.golang.org/welcome/1
  • https://github.com/zimbatm/direnv
  • Go 웹 애플리케이션 개발 휴대폰
  • Why I Don’t Use Go Web Frameworks
  • 시리즈


    Part1Part1.5

    좋은 웹페이지 즐겨찾기