- 投稿日:2020-09-07T22:23:05+09:00
Golang チュートリアル その1
概要
「処理が速い」「並行処理」が得意ということから、
今後大規模webサービスなどで重宝されると思いましたので、
学習していきたいと思います。参考サイト
以下を実施してみました。
環境
GoogleChrome
※ブラウザ操作だけで学習できるため、エディタを用意する必要がありません。
※CentOS8へのGoインストール手順です。よろしければ、ご活用ください。
CentOS8へのGo言語インストール手順基本操作
Hello Worldの実行手順です。
基本的な書き方
Packages, variables, and functions.
Go プログラムの基本的なコンポーネントを学びます。
- 「package main」から始まる。
すべてはここから始まる
- 関数について
引数に設定する関数には、型名を書く必要がある
//xとyが該当 func add(x int, y int) int { return x + y }ただし、関数の2つ以上の引数が同じ型である場合には、最後の型を残して省略して記述できる。
//xとyが該当 func add(x, y int) int { return x + y }
- 関数は複数の戻り値を返すことができる
func.gopackage main import "fmt" //関数側 func swap(x, y string) (string, string) { return y, x } //呼び出す側 func main() { a, b := swap("hello", "world") fmt.Println(a, b) } //実行 go run func.go //実行結果 world hello
- 戻り値となる変数に名前をつける
戻り値となる変数に名前をつけることができる。
戻り値に名前をつけると、関数の最初で定義した変数名として扱われます。名前をつけた戻り値の変数を使うと、
return ステートメントに何も書かずに戻すことができる。
※長い関数で使うと読みやすさ( readability )に悪影響があるため、
注意が必要。returnValueName.gopackage main import "fmt" //(x, y int)の部分が名前付き変数 func split(sum int) (x, y int) { x = sum * 4 / 9 y = sum - x return } func main() { fmt.Println(split(17)) } //実行 go run returnValueName.go //実行結果 7 10変数
- 変数の宣言
「var」ステートメントで変数の宣言を行う。
パッケージ、または、関数で利用できる。var.gopackage main import "fmt" //グローバルに宣言 ※boolが型 var c, python, java bool func main() { var i int fmt.Println(i, c, python, java) } //実行 go run var.go //実行結果 0 false false false
- 変数に初期値を与える
初期値が与えられている場合、型を省略できる。
その変数は初期値が持つ型になります。
※例: 数字->int , 文字列->stringなどgiveVarInitialValue.gopackage main import "fmt" var i, j int = 1, 2 func main() { //c->bool ,python->bool ,java->string var c, python, java = true, false, "no!" fmt.Println(i, j, c, python, java) } //実行 go run giveVarInitialValue.go //実行結果 1 2 true false no!
- 変数の宣言を省略
関数の中では、 var 宣言の代わりに、短い := の代入文を使い、
暗黙的な型宣言ができる。※関数の外では、キーワードではじまる宣言( var, func, など)が必要で、 := での暗黙的な宣言は利用できない。
varDeclarationOmitted.gopackage main import "fmt" func main() { var i, j int = 1, 2 //暗黙的宣言 k := 3 c, python, java := true, false, "no!" fmt.Println(i, j, k, c, python, java) } //実行 go run varDeclarationOmitted.go //実行結果 1 2 3 true false no!
- 基本の型
次のとおりです。
//型の紹介のみ bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr byte // uint8 の別名 rune // int32 の別名 // Unicode のコードポイントを表す float32 float64 complex64 complex128
- 変数に初期値を与えずに宣言
その場合、ゼロ値が与えられます。
ゼロ値は型によって以下のように与えられる。
数値型(int,floatなど): 0
bool型: false
string型: "" (空文字列( empty string ))varNoInitialVal.gopackage main import "fmt" func main() { var i int var f float64 var b bool var s string fmt.Printf("%v %v %v %q\n", i, f, b, s) } //実行 go run go:varNoInitialVal.go //実行結果 0 0 false ""
- 型変換
少数点→整数の変換について
※数値から文字列への変換に関しては、また別処理が必要。。
golang 文字列→数値、数値→文字列変換typeConv.gopackage main import ( "fmt" "math" ) func main() { var x, y int = 3, 4 var f float64 = math.Sqrt(float64(x*x + y*y)) var z uint = uint(f) fmt.Println(x, y, z) } //実行 go run typeConv.go //実行結果 3 4 5
- 型推論
明示的な型を指定せずに変数を宣言する場合( := や var = のいずれか)、
変数の型は右側の変数から型推論される。
※右側の変数が型を持っている場合、左側の新しい変数は同じ型になる。typeInference.go// i はint型のため、vもint型になる。 package main import "fmt" var i int func main() { v := i fmt.Printf("v is of type %T\n", v) } //実行 go run typeInference.go //実行結果 v is of type int定数
定数は、 constを使って変数と同じように宣言する。
定数は、文字(character)、文字列(string)、boolean、数値(numeric)のみで使える。
※定数は := を使って宣言できない。constant.gopackage main import "fmt" const Pi = 3.14 func main() { const World string = "世界" fmt.Println("Hello", World) fmt.Println("Happy", Pi, "Day") const Truth = true fmt.Println("Go rules?", Truth) } //実行 go run constant.go //実行結果 Hello 世界 Happy 3.14 Day Go rules? trueまとめ
基本的なところをみていきました。
次回は、「For」や「if」といったところをみていきます。
- 投稿日:2020-09-07T22:07:39+09:00
vim-goimportsが効かない時の対処法。
はじめに
Vimに vim-goimports を追加してみたものの効かなかったので対処法を記しておきます。
対処法
なぜ効かなかったかといいますと、~/.zshrc に$GOBINを通していなかったからです。
ということで、~/.zshrcに以下を書くだけです。.zshrcexport GOBIN="$GOPATH/bin"
- 投稿日:2020-09-07T22:06:27+09:00
GoでVercel Serverless Functions
ホスティングサービスをNetlifyからVercelに乗り換えたついでにServerless Functionsが気になったので試してみました。
Vercel
Next.jsの運営元であるVercel(元Zeit)のWebアプリケーションホスティングサービスです。ちょうどNetlifyとかと同じポジションですね。
前準備
アカウント作成
Vercelのトップページの右上にあるSignUpボタンからGithub, GitLab, BitBucketのアカウントを使用してアカウント作成をします。
Vercel CLI
npmパッケージとして提供されているVercel CLIをインストールします。
これは主にローカルからデプロイを行う際に使用します。npmnpm i -g vercel
yarnyarn global add vercelインストール後
vercel loginを実行し、上で登録したemailアドレスの入力と確認を済ませます。
サーバーレス関数の作成
プロジェクトフォルダの直下に
index.go
を作成します。
このindex.go
はhttp.ResponseWriter
と*http.Request
を引数として持つ関数が存在する必要があります。
まずはVercel Serverless Functions Go Example
というテキストを返すだけの関数を実装します。index.jspackage main import ( "fmt" "net/http" ) func Handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Vercel Serverless Functions Go Example") }vercel.jsonの作成
vercel.json{ "version": 2, "name": "go", "builds": [ { "src": "*.go", "use": "@vercel/go" } ] }ルーティング
日時を返すエンドポイントを作成していきます。
今回はわかりやすく下記のようにエンドポイントごとにフォルダを分けて作成します。root ├ /date │ └ index.go └ index.go型の作成
date/index.gotype ResDate struct { Date string `json:"date"` }リクエストハンドラの実装
w.Header().Set("Content-Type", "application/json")
でContent-Type
の指定を行います。date/index.gofunc Handler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") d := ResDate{ time.Now().Format(time.RFC850) } bytes, _ := json.Marshal(d) fmt.Fprintf(w, string(bytes)) }date/index.go
date/index.gopackage date import ( "fmt" "net/http" "time" "encoding/json" ) type ResDate struct { Date string `json:"date"` } func Handler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") d := ResDate{ time.Now().Format(time.RFC850) } bytes, _ := json.Marshal(d) fmt.Fprintf(w, string(bytes)) }vercel.jsonでルーティングの設定
ルーティングの設定を行うために
vercel.json
にroutes
の要素を追加します。routes"routes": [ { "src": "/date", "dest": "/date" } ]加えて、ビルド対象フォルダに先程作成した
date
フォルダ内のgo
ファイルを追加します。builds"builds": [ { "src": "*.go", "use": "@vercel/go" }, { "src": "/date/*.go", "use": "@vercel/go" } ]vercel.json{ "version": 2, "name": "go", "builds": [ { "src": "*.go", "use": "@vercel/go" }, { "src": "/date/*.go", "use": "@vercel/go" } ], "routes": [ { "src": "/date", "dest": "/date" } ] }デプロイ
vercelこれだけです。
本番デプロイをするのであれば
--prob
オプションをつけるだけです。vercel --prob
デプロイ後の以下のURLにアクセスすると
https://go-vercel-function-example.mugi111.vercel.app
一番最初に作成した関数通りVercel Serverless Functions Go Example
と表示されているのが確認できました。
dateエンドポイントも正常に動作していることが確認できました。
https://go-vercel-function-example.mugi111.vercel.app/date
- 投稿日:2020-09-07T21:34:22+09:00
CentOS8にGolangをインストールする
概要
Golang学習用備忘録です。
今回以下URLを参考にさせていただきました。VMwareにCentOS8を構築
以下に記載しておりますので、
よろしければ、ご覧ください。Windows10にVMwareで仮想サーバを構築し、Dockerを使ってみる
Golangインストール/動作確認
- Goインストール
ターミナル#Golangインストール dnf install -y epel-release dnf install -y golang #Golangバージョン確認 go version →「go version go1.13.4」と表示される
- 動作確認(Goファイル作成)
ターミナル#動作確認用Goファイル作成 vim hello.go #以下を追記 package main import "fmt" func main(){ fmt.Println("hello world") } #動作確認 go run hello.go #以下のように表示されること hello worldまとめ
次回は、Goのチュートリアルについてまとめていきたいと思います。
- 投稿日:2020-09-07T17:17:26+09:00
【GCP】Cloud BuildでCI/CDパイプラインを構築する。
はじめに
Cloud BuildはGCP上でCI/CDを行うためのサービスです。
特にコンテナを扱ったソリューションと相性がよく、
テストやビルドはGCP上にプロビジョニングされたコンテナ内で行われ、
Cloud FunctionsやCloud Runといった様々なコンピューティングサービス上にデプロイすることができます。本記事では、
- ソースコードの管理:Cloud Source Repositories
- テスト及びビルド:Cloud Build
- コンテナレジストリ:Container Registry
- デプロイ:Cloud Run
の全てGCP内で完結するリソースを使ってコンテナアプリケーションにおけるCI/CD環境を構築したいと思います!
本記事で使用したソースコードは、こちらにあります。開発環境
- macOS Catalina 10.15.6
- Docker Desktop stable 2.3.0.4
- Google Cloud SDK 308.0
登場人物たち
Cloud Source Repositories
プライベートなGitリポジトリをホスティングできるサービスです。
https://cloud.google.com/source-repositories/docs?hl=jaContainer Registry
プライベートなDockerイメージをホスティングできるサービスです。
https://cloud.google.com/container-registry/docs?hl=jaCloud Run
マネージドなコンテナ実行プラットフォームです。
コンテナを手軽にサービスとしてデプロイ、公開可能です。
https://cloud.google.com/run/docs?hl=jaCloud Build
本記事の主役です。
冒頭にもあるように、マネージドなCI/CD環境を構築できます。
詳しくは後の項で説明しますが、ビルドコンテナ内でgcloudコマンド叩けたりと柔軟なシナリオが作成可能です。
https://cloud.google.com/cloud-build/docs?hl=ja作ってみよう!
ローカルにGitリポジトリを作成
適当な空のディレクトリを作成し、
git init
を行います。$ mkdir cloudbuild-sample && cd cloudbuild-sample $ git initサンプルアプリケーションの作成
Cloud Runにデプロイするアプリケーションを作成します。
AとBの和を返す簡単なアプリを考えます。$ mkdir workspacecloudbuild-sample/workspace/go.modmodule mymod go 1.15cloudbuild-sample/workspace/main.gopackage main import ( "encoding/json" "fmt" "log" "mymod/utils" "net/http" ) func main() { mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { j := json.NewDecoder(r.Body) var req struct { A int `json:"a"` B int `json:"b"` } j.Decode(&req) fmt.Fprintf(w, "%d\n", utils.Add(req.A, req.B)) }) log.Println("start server...") http.ListenAndServe(":8080", mux) }足し算の関数を定義するサブパッケージを作成します。
$ mkdir workspace/utilscloudbuild-sample/workspace/utils/add.gopackage utils // Add return a + b func Add(a int, b int) int { return a + b }cloudbuild-sample/workspace/utils/add_test.gopackage utils import "testing" func TestSuccessAdd(t *testing.T) { expect := 3 result := Add(2, 1) if expect != result { t.Fatalf("result is expected %d, got %d ", expect, result) } } func TestFailureAdd(t *testing.T) { t.Fatal("FAILURE!!") }CI実行時にテストの失敗を考慮されるかを確認するため、意図的に失敗するテストコードを作成しました。
さらに、公開用のDockerイメージファイルも作成します。
cloudbuild-sample/DockerfileFROM golang:1.15-alpine as builder WORKDIR /opt/build COPY go.* ./ RUN go mod download COPY . ./ RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o app FROM alpine:3.12 ENV PORT 8080 COPY --from=builder /opt/build/app /opt/app WORKDIR /opt CMD ["./app"]お疲れ様です!
上記のアプリは、$ curl -X POST -H "Content-Type: application/json" -d '{"a":41, "b":10}' http://localhost:8080 51のようなリクエストに対して、aとbの和を返してくれます。
gcloudコマンドの下準備
前提として、既にGCPプロジェクトが作成済みでgcloudコマンドが使用できることを確認してください。
ここではパイプライン環境構築のためのGCPプロジェクト側での設定を行います。まずは利用するサービスのAPIを有効化しましょう!
$ gcloud services enable sourcerepo.googleapis.com \ run.googleapis.com \ cloudbuild.googleapis.com \ containerregistry.googleapis.com次にSource Repositoriesにリポジトリを作成し、リモートにセットします。
$ gcloud source repos create cloudbuild-sample $ git remote add google https://source.developers.google.com/p/{YOUR_PROJECT_ID}/r/cloudbuild-sampleさらにリポジトリに対し認証情報を付与します。
$ git config --local credential.https://source.developers.google.com.helper gcloud.shここまでのコードをpushできるか確認してましょう。
$ git add . $ git commit -m 'first commit' $ git push google master次にCloud Buildのサービスアカウントに対しCloud Runへデプロイするための役割を付与します。
$ gcloud projects add-iam-policy-binding {YOUR_PROJECT_ID} \ --member serviceAccount:{YOUR_PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role roles/run.admin $ gcloud projects add-iam-policy-binding {YOUR_PROJECT_ID} \ --member serviceAccount:{YOUR_PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \ --role roles/iam.serviceAccountUserお疲れ様です!
これで下準備は完了です。Cloud Buildの構成ファイルを作成する。
Cloud Buildではテストやビルドの手順をYAMLファイルとして定義します。
簡単な例として、前項で作成したサンプルアプリケーションのテストを実行し、
成功したらデプロイ用のイメージをビルドする手順書を作成してみます。cloudbuild-sample/cloudbuild.yamlsteps: # steps下にテスト〜デプロイまでの各手順を定義します。 - name: 'golang:1.15-alpine' # コマンドを実行するコンテナイメージ id: 'do testing' # 各ステップを表す識別子 entrypoint: '/bin/sh' # コンテナが実行される際のエントリーポイント env: # コンテナが実行される際に渡される環境変数 - 'CGO_ENABLED=0' dir: 'workspace' # エントリーポイントが実行されるディレクトリ args: # エントリーポイントに対する引数 - '-c' - | go mod download \ && go test mymod/... - name: 'gcr.io/cloud-builders/docker' # 注1 id: 'do building' args: # エントリーポイントは docker です。 - 'build' - '-t' - 'gcr.io/$PROJECT_ID/sample_app:$SHORT_SHA' # 注2 - '-f' - './Dockerfile' - './workspace'設定しているオプションをよく見てみると、
普段のdocker run
コマンドを構成するオプションと似ていることが確認できるかと思います。注1
nameオプションに設定できるコンテナイメージですが、
クラウドビルダーと呼ばれるGCP側で用意された特別なコンテナイメージも利用可能です。
クラウドビルダーコンテナにはIAM等が適切に割り当てられた環境でgcloud
コマンド等が実行できるため、
柔軟なパイプラインを作成することが可能になります。
利用可能なクラウドビルダーについては
https://cloud.google.com/cloud-build/docs/cloud-builders?hl=ja
を確認してみてください。注2
$PROJECT_ID
や$SHORT_SHA
といった、いくつかの変数はCloud Build側で適切な値に自動で置換されます。
今回の例で使用した
$PROJECT_ID
は、GCPプロジェクトのID
$SHORT_SHA
は、ビルドをトリガーしたリポジトリへのコミットID
です。
変数値の置換については、
https://cloud.google.com/cloud-build/docs/configuring-builds/substitute-variable-values?hl=ja
を確認してみてください。それでは完全なCloud Buildの構成ファイルを作成してみましょう!
下記の構成ファイルでは、
go test
を実行しテストが全てパスされるかを確認- デプロイ用のコンテナイメージをビルド
- ビルドされたコンテナイメージをGCRへpush
- GCRへプッシュされたイメージを使い、Cloud Runへサービスをデプロイ
を行います。
cloudbuild-sample/cloudbuild.yamlsteps: - name: 'golang:1.15-alpine' id: 'do testing' entrypoint: '/bin/sh' env: - 'CGO_ENABLED=0' dir: 'workspace' args: - '-c' - | go mod download \ && go test mymod/... - name: 'gcr.io/cloud-builders/docker' id: 'do building' args: - 'build' - '-t' - 'gcr.io/$PROJECT_ID/sample_app:$SHORT_SHA' - '-f' - './Dockerfile' - './workspace' - name: 'gcr.io/cloud-builders/docker' id: 'do pushing image' args: - 'push' - 'gcr.io/$PROJECT_ID/sample_app:$SHORT_SHA' - name: 'gcr.io/cloud-builders/gcloud' id: 'do deploying' args: - 'run' - 'deploy' - 'sample-app' - '--image=gcr.io/$PROJECT_ID/sample_app:$SHORT_SHA' - '--region=asia-northeast1' - '--platform=managed' - '--allow-unauthenticated'お疲れ様です!
パプリックなコンテナイメージとクラウドビルダーを使い分け様々なシナリオに対応できることが実感できたかと思います。
構成ファイルに関する正確な情報はこちらをご確認ください。
https://cloud.google.com/cloud-build/docs/build-config?hl=jaSource Repositoriesへのpushでビルドをトリガーする。
最後に、Source Repositoriesへコードがプッシュされたときに自動的にCloud Buildが走るようトリガーを設定します。
$ gcloud beta builds triggers create cloud-source-repositories \ --repo cloudbuild-sample \ --branch-pattern="master" \ --build-config cloudbuild.yamlcloudbuild-sampleリポジトリのmasterブランチにコードがpushされた際に、
cloudbuild.yamlに定義された内容のパイプラインが実行されます。お疲れ様です!
作業は以上となります。
それではビルドの様子を確認していきたいと思います。ビルドを実行してみよう!
これまでの内容をpushし、Cloud Buildが実行されるか確認してみます。
$ git add . $ git commit -m 'second commit' $ git push google master下記のURLからビルドの履歴を確認できます。
https://console.cloud.google.com/cloud-build/builds?hl=ja今回のビルドでは
go test
に失敗し、ビルドが途中で中断されていることが確認できるかと思います。テストコードを修正し、もう一度ビルドを実行しましょう。
cloudbuild-sample/workspace/utils/add_test.gopackage utils import "testing" func TestSuccessAdd(t *testing.T) { expect := 3 result := Add(2, 1) if expect != result { t.Fatalf("result is expected %d, got %d ", expect, result) } } func TestFailureAdd(t *testing.T) { // t.Fatal("FAILURE!!") # コメントアウトしました。 }再びpushします。
$ git add . $ git commit -m 'fix test code' $ git push google masterビルドが正常に完了したことを確認します。
https://console.cloud.google.com/cloud-build/builds?hl=jaさらに、正常にCloud Runへデプロイされたかを確認しましょう!
https://console.cloud.google.com/run?hl=jaサービスのURLを確認し、curlを叩いてみます。
$ curl -X POST -H "Content-Type: application/json" -d '{"a":41, "b":10}' YOUR_CLOUD_RUN_URL 51お疲れ様でした!
終わりに
本記事ではCloud Buildを使ってGo言語アプリケーションのCI/CDパイプラインを構築しました。
テストやビルドには様々なコンテナイメージを使えるためGo言語に限らず、柔軟なパイプラインを構築できるかと思います!
ありがとうございました!
- 投稿日:2020-09-07T16:05:40+09:00
[自分用メモ] はじめてのGoogle Cloud Functions(Go言語編)
注意
ここに書かれていることは、すべて下記の公式ドキュメントに書かれているものです。このブログは、あくまで自分用メモになります。
公式ドキュメント → https://cloud.google.com/functions/docs
Google Cloud FunctionsとGo
Goが使えるようになったのは2019年1月(参考記事)。
2020年9月現在、使えるGoのバージョンは1.11と1.13のみ(参考記事)。
関数を作る
ローカルの開発環境に、適当に次のような関数を作る。
hello.gopackage hello import ( "fmt" "net/http" ) func Hello(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!") }外部ライブラリとかを使いたければ、go.modを書けば良い。
GCPプロジェクト作成
適当にプロジェクトを作っておく。
ここに書いてある「APIの有効化」とかが必要かも。
gcloudコマンドでデプロイ
事前準備# ログイン $ gcloud auth login # 操作対象のプロジェクトを設定 $ gcloud config set project プロジェクトID関数のデプロイ$ gcloud functions deploy Hello --runtime go113 --trigger-http --allow-unauthenticated
Hello
の部分は、Goで書いた関数名と揃える必要があるっぽい。実行
先ほどの
gcloud functions
コマンドの結果に、次のようなものが含まれている。このURLにアクセスすればよい。httpsTrigger: url: https://us-central1-my-first-function-xxxxxx.cloudfunctions.net/Hello
- 投稿日:2020-09-07T07:50:12+09:00
Goプロジェクトのはじめかたとおすすめライブラリ8.5選。ひな形にも使えるサンプルもあるよ。
(記事を読んで参考になったなとかストックしとこ、って思って頂けたらぜひLGTMもして頂けると喜びます?)
はじめに
最近イケイケなGo!
でもベターなGoプロジェクトのはじめかたっていまいち調べてもわからないですよね。
自分は最初色々迷いました。。まずパッケージ管理ツール。
godepだったりGo Modulesだったり、少し情報がとっちらかっている印象です。後はどのディレクトリにプロジェクトを配置した方がいいのかもわかりづらい。
importの仕方も相対と絶対のどちらがいいのか迷う。というわけで以下の4点に絞って解説していきたいと思います!
- パッケージ管理ツール
- プロジェクトの配置場所
- 自作パッケージのimportの仕方
- おすすめライブラリ
この記事を読めば正しくGoプロジェクトが作成できます!(たぶん)
【追記】
インストール方法とVSCodeの設定に関しても簡潔にまとめたので、良かったら参考にしてください。
【超簡単】GoのインストールとVSCode設定方法いきなりまとめ
プロジェクト作成
新規にGoプロジェクトを作成したい場合は以下の通りにコマンドを実行すればOKです。
$ cd (任意のディレクトリ) $ mkdir (YOUR_PROJECT) $ cd (YOUR_PROJECT) $ go mod init github.com/(GitHubユーザ名)/(GitHubリポジトリ名) # 後はどんどこファイル作成! $ vim main.go # あるいは必要なパッケージをインストール $ go get ~~~~~ ...おすすめライブラリインストール
go mod init
後に必要に応じて実行。
あるいは各ソースコードのimport文にライブラリのパスを記載しておくと、go run
の時に自動でインストールしてくれます。go get -u github.com/labstack/echo/... go get -u github.com/joho/godotenv go get -u github.com/sirupsen/logrus go get -u github.com/valyala/fasthttp go get -u github.com/golang/mock/gomock go install github.com/golang/mock/mockgen go get -u github.com/google/wire/cmd/wire go get -u gorm.io/gorm go get -u gorm.io/driver/mysql # mysqlを使う場合 go get -u github.com/oxequa/realizeサンプル
あくまでも簡易的なものです。。
こちら(GitHub)です。パッケージ管理ツール
簡単に説明
現在はGo Modulesが標準なのでこちらの機能を使いましょう。
Go Modulesが標準で使えるようになる前は、godepなどが使われていたらしいです。Go言語の依存モジュール管理ツール Modules の使い方
Modules は、依存モジュール管理ツールです。
Go言語 1.11 から標準で使えるようになりました。
以下のような機能を持っています。・依存モジュールの自動検知
・依存モジュールのバージョン固定、バージョンアップ検知
・依存モジュールの情報は go.mod と go.sum という名前のファイルに記載されます。使い方
新規にディレクトリを作成し、
go mod init
と打つだけで、Go Modulesを使えるようになります。$ mkdir (YOUR_PROJECT) $ cd (YOUR_PROJECT) $ go mod init github.com/(GitHubユーザ名)/(GitHubリポジトリ名) go: creating new go.mod: moduleそうすると、
go.mod
ファイルが(YOUR_PROJECT)
直下に作成されます。go.modmodule github.com/(GitHubユーザ名)/(GitHubリポジトリ名) go 1.15ライブラリをインストールすると、そのファイル内にパッケージの依存情報が記載されます。
かんたん便利!モジュール名
go mod init
でモジュール名(プロジェクト名)を指定する時は、慣習的にgitリポジトリのドメインから記載するようです。
色々漁ってみたんですけどソースはいまいちわかりませんでした。。
ただ、The Go Blog - Using Go Modulesでもそのように紹介されていました。例えば私だと以下の通りです。
$ go mod init github.com/yagi-eng/go-pj-templateリポジトリURLはこちら。
https://github.com/yagi-eng/go-pj-templateGitHub以外、例えばCodeCommitだとこうなるらしい。
$ go mod init git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/hello.gitプロジェクトの配置場所
簡単に説明
Go Modulesの登場により、どこでも配置できるようになりました。
以上です。以前は
Go Modulesの登場以前は
$GOPATH/src
(※)配下に配置する必要がありました。
他言語からくると、置く場所が決まっている点に少し戸惑いますが、解消されたようです。※
$GOPATH
はデフォルトだと$HOME/go
どこでも配置できるようになったけど、なんかGoっぽいので自分は以下の例の通りに配置しています。
具体例
$GOPATH ├─ bin/ ├─ pkg/ └─ src/ └─ github.com/ └─ GitHubユーザ名/ └─ GitHubリポジトリ名/ ├─ main.go └─ などなど。気の向くままに配置。自分の場合はこんな感じです。
$GOPATH ├─ bin/ ├─ pkg/ └─ src/ └─ github.com/ └─ yagi-eng/ └─ go-pj-template/ ├─ main.go └─ などなど。気の向くままに配置。$GOPATH/src/github.com/yagi-eng/go-pj-templete自作パッケージのimportの仕方
簡単に説明
import "(モジュール名)/(自作パッケージ名)"相対パスではなく、モジュール名から始まる絶対パスで指定します。
具体例は次の通りです。具体例
モジュール名:
github.com/yagi-eng/hoge-pj
自作パッケージ名:hoge
ディレクトリ構成hoge-pj/ ├─ hoge/ #自作パッケージ | └─ hoge.go ├─ main.go └─ go.modgo.modmodule github.com/yagi-eng/hoge-pj go 1.15hoge.gopackage hoge // 自作パッケージ import "fmt" func PrintHoge() { fmt.Println("hogehoge") }main.gopackage main import "github.com/yagi-eng/hoge-pj/hoge" // こんな感じでimport! func main() { hoge.PrintHoge() }こんな感じでimportすれば実行できます。
$ go run main.go hogehogeおすすめパッケージ
インストールしておくと捗りそうなパッケージを紹介します。
パッケージのインストール方法
以下のコマンドを実行するだけです。Go Modulesがいい感じにインストールしてくれます。
$ go get -u (インストールしたいパッケージ名) # 例 echoフレームワークをインストールする場合 $ go get -u github.com/labstack/echo/...echo
Goの軽量フレームワーク。
簡単にルーティングやサーバ実行、ロギング、CORS設定などをすることができます。公式HPはこちら。
$ go get -u github.com/labstack/echo/...godotenv
.env
ファイルを使用するためのライブラリ。使い方は以下の記事が参考になります。
【Go】.envファイルをGolangでも使用するためのライブラリ「godotenv」$ go get -u github.com/joho/godotenvlogrus
logの外部パッケージ。
Go標準パッケージのlog
はシンプル過ぎるので、ログレベルなど使いたい時に便利です。【Go×ログ】logrusの使い方を簡単に分かりやすくまとめてみた
$ go get -u github.com/sirupsen/logrus【追記】zap
こちらもlogの外部パッケージ。
記事を読んで頂いた方に紹介頂きました!
logrus
より高速なようです。
こっちを使った方が良さそうですね。
- uber-go/zap
- README.mdにパフォーマンスに関して言及されています。
- golangの高速な構造化ログライブラリ「zap」の使い方
$ go get -u go.uber.org/zapfasthttp
go言語でHTTP通信を行うためのライブラリです.
go言語の標準パッケージではnet/httpがすでに用意されているのですが,
fasthttpでは標準パッケージを凌駕する処理の速さで一時期有名になりました.
公式のベンチマークでは,従来に比べ10倍の差がでたようです.$ go get -u github.com/valyala/fasthttpgomock
mock生成ライブラリ。
簡単にモックを作成できるので、テストを実装する時などに便利です。$ go get -u github.com/golang/mock/gomock $ go install github.com/golang/mock/mockgenwire
DIライブラリ。いい感じにDIできます。
$ go get -u github.com/google/wire/cmd/wiregorm
GoのORマッパー。
2020年8月にVersion2.0がリリースされて、使い勝手が向上したみたいです。$ go get -u gorm.io/gorm $ go get -u gorm.io/driver/mysql # mysqlを使う場合realize
hot reloadライブラリ。
Goはコンパイル言語なので、PHPのように変更が即反映されず、変更のたびにプロセスをキルしてgo run
し直す必要があります。
その点を解消してくれます。ただし、Go Modulesを使っている場合はそのままだと動作しません。
ワークアラウンドをあてる必要があります。
- [Go] Realizeが便利なので、もう少し仲良くなってみる
- Cannot do
--run
with go1.11 using go mod under windows.
- ワークアラウンドはこちら。
$ go get -u github.com/oxequa/realize補足
realizeはファイルが更新された際に、今動いているアプリを停止しないまま更新後のアプリを起動させようとします。
そのため、ポート番号を指定してGoサーバを起動していると、以下のようなエラーが出てうまくhot reloadされません。{"time":"2020-09-04T15:29:06.6074496+09:00", "level":"FATAL","prefix":"echo","file":"server.go","line":"41", "message":"listen tcp :8080: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted."}こちらもワークアラウンドが出てます。
Realize is not killing the current appreflex
こちらもhot reloadライブラリ。
2つ目のhotreloadライブラリなので0.5扱いです。
realizeがダメだったら試してみるといいかも。
ただし、Windowsには対応していません。goのhot reloadingにはreflexが便利だった
$ go get -u github.com/cespare/reflex【追記】air
こちらもhot reloadライブラリ。
記事を読んで頂いた方に紹介頂きました!
自分はrealize
もreflex
も使えなかったので結局こちらを使っています。$ go get -u github.com/cosmtrek/airサンプル
こちら(GitHub)です。
はじめかた
# MySQL準備 $ docker-compose up -d # migration実行 $ go run tools/migrate.go # アプリ実行 $ go run server.go説明
Goをいい感じに始められるサンプル・ひな形です。
Goがインストールしてあることを前提としています。
簡単なAPIサーバを立てる時や、Goを始めたばかりでどうプロジェクトを作成していけばいいかわからない時に有効だと思います。本格的なGoプロジェクトを作る時には不向きです。
コードを読むとおわかり頂けるのですが、db *gorm.DB
を引きずりまわしているのでその点が辛みです。
本格的なプロジェクトを作成する際は、wire
などのDIライブラリを使うと捗ると思います。
go.mod
に記載されているライブラリに関しては、以下のQiitaを参照ください。
wire
やgomock
などはインポートはしましたが、サンプルでは使っていません。
記念に入れておいただけなので、go mod tidy
すると消えます。サンプルに含まれる内容
gorm
を使ったMySQL接続gorm
を使ったDB migrationのサンプルgorm
を使ったDB Read/Writeのサンプルecho
を使ったルーティング、ロギング、CORS設定godotenv
を使った.env
ファイルの読み込み本格的なGoプロジェクトに興味のある方は。。
手前みそですが、こちらの記事が参考になるかと思います。
Goとクリーンアーキテクチャで飲食店検索ができるLINE BOT作ってみた以下のように、結構ゴリゴリつくりました笑
|--.env |--docker-compose.yml |--go.mod // Goのバージョン管理 |--Procfile // Herokuデプロイ |--server.go // main関数 |--wire.go // DI用 |--domain | |--model | |--repository // databaseのinterface |--infrastructure | |--database | |--mysql.go | |--router.go // Routing |--interfaces | |--controllers | |--gateway // 外部API通信 | |--presenter // LINE BOT出力 |--mock // 各層のmock | |--gateway | |--presenter | |--repository |--tools // DBマイグレーション |--usecases | |--dto // usecase用のDTO | | |--favoritedto | | |--googlemapdto | | |--searchdto | |--igateway // interfaces/gatewayのinterface | |--interactor | | |--usecase // usecases/interactorのinterface | |--ipresenter // interfaces/presenterのinterfaceさいごに
Twitterの方でも、モダンな技術習得やサービス開発の様子を発信したりしているので良かったらチェックしてみてください!
Goのプロジェクトのはじめ方や、おすすめのライブラリをQiitaにまとめました?
— やぎぬ?行動力エンジニア (@yagi_eng) September 6, 2020
Goのこの辺りの情報ってあまりまとまっていないので、Goに興味のある方やGo初心者の方には参考になると思います?
特にパッケージ管理やディレクトリ配置などは最初は「ん?」ってなりがち?https://t.co/gLNPlPLzbU参考記事