【Go Lang】WebFrameWork使ってみた1 Gin

# はじめに

筆者について。
- SIer界隈の人
- 東京以外の地方都市在住
- 30代後半

GoLang案件がなんだか増えてきた。
ということで導入のテンプレートになるWebFWを作りたい。
そのベースとなるWebFrameWorkについて、実際に使ってみて導入の検討をしていくことにする。
観点は以下！

- 人気
- 学習しやすさ
- 特徴

[【Go Lang】WebFrameWork使ってみた1 Gin](https://qiita.com/y_nomura_CR/items/9858f2c1e4e1b4d2d2d3)
[【Go Lang】WebFrameWork使ってみた2 beego](https://qiita.com/y_nomura_CR/items/1029d6cd1e24d61831f1)
[【Go Lang】WebFrameWork使ってみた3 iris](https://qiita.com/y_nomura_CR/items/d24f243d7b34522626d5)

# 使ってみるWebFrameWork
[GitHubリポジトリのスター数でOSSランキングを作成する](https://qiita.com/loftkun/items/5ea5b9577347505729f6)
を参考にGitHubリポジトリのスター数をカウントしてみた。
※jqはダウンロードしてきてpathを通す必要あり

```
$ set LANGUAGE=go
$ set KEYWORD=web+framework
$ set STAR=10000
$ set USER=yusuke-nomura-cosmoroot
$ set PASS=20130401_cosmo
$ set page=1
$ curl --anyauth --user %USER%:%PASS% "https://api.github.com/search/repositories?q=%KEYWORD%+in:name,description,readme+language:%LANGUAGE%+stars:>=%STAR%&sort=stars&order=desc&per_page=10&page=%page%" | jq -r ".items[] | [.full_name , .stargazers_count, .html_url, .description] | @csv"
```

#### 結果

|full_name|stargazers_count|html_url|description|
|:--|:--|:--|:--
| avelino/awesome-go       | 61278 | https://github.com/avelino/awesome-go       | A curated list of awesome Go frameworks, libraries and software                                                                                                                                                                              | 
| gin-gonic/gin            | 45306 | https://github.com/gin-gonic/gin            | Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.                                           | 
| beego/beego              | 25835 | https://github.com/beego/beego              | beego is an open-source, high-performance web framework for the Go programming language.                                                                                                                                                     | 
| kataras/iris             | 20001 | https://github.com/kataras/iris             | The fastest HTTP/2 Go Web Framework. AWS Lambda, gRPC, MVC, Unique Router, Websockets, Sessions, Test suite, Dependency Injection and more. A true successor of expressjs and laravel \| 隹｢隹｢ https://github.com/kataras/iris/issues/1329 \| | 
| go-kit/kit               | 19253 | https://github.com/go-kit/kit               | A standard library for microservices.                                                                                                                                                                                                        | 
| labstack/echo            | 19081 | https://github.com/labstack/echo            | High performance, minimalist Go web framework                                                                                                                                                                                                | 
| valyala/fasthttp         | 14343 | https://github.com/valyala/fasthttp         | Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http                                                                                                                   | 
| gocolly/colly            | 12997 | https://github.com/gocolly/colly            | Elegant Scraper and Crawler Framework for Golang                                                                                                                                                                                             | 
| jaegertracing/jaeger     | 12736 | https://github.com/jaegertracing/jaeger     | CNCF Jaeger, a Distributed Tracing Platform                                                                                                                                                                                                  | 
| julienschmidt/httprouter | 12308 | https://github.com/julienschmidt/httprouter | A high performance HTTP request router that scales well                                                                                                                                                                                      | 


awesome-go→awesomeなgoのライブラリとかの紹介なので除外。
というわけで1~3位を使ってみることにする。

- Gin←今回はコレ
- beego
- iris

# 公式サイトとか
公式サイト（日本語対応）：https://gin-gonic.com/ja/
github:https://github.com/gin-gonic/gin
ライセンス:MIT


# 人気
- star数:45,306
- qiitaの記事数：140（https://qiita.com/tags/gin）
- google検索結果：約 7,120,000 件（検索ワード"go lang gin"）

star数はbeegoを大きく引き離している。
qiitaのトレンドは古い記事が多いような。

# 学習しやすさ
日本語ドキュメント対応。


# 特徴
> httprouter のおかげでそれより40倍以上も速いパフォーマンスがあります。
> HTTP リクエストの処理中に発生した panic を recover します。
> JSON によるリクエストを解析してバリデーションすることができます。
> HTTP リクエスト中に発生したすべてのエラーを収集するための便利な方法を提供します。
> JSON、XML、およびHTMLでレンダリングするためのの使いやすいAPIを提供します。


# 実装
[ginを最速でマスターしよう](https://qiita.com/Syoitu/items/8e7e3215fb7ac9dabc3a)
を参考にファイルアップロードサンプルを作成する。

> gomodを使用することをお勧めします。

gomodとはなんぞや？
goのパッケージ管理ツールらしい。

> GOMODULEが誕生される前に GOPATH と GOVENDORを使用してパッケージの管理をするのが一般的でした。
> でも、どっちを使用しても、便利とは言えない

ですよねーはじめてのGo読んでてそう思ってました。
npmみたいなものか。
理解したのでサクサク進める。

GOMODULEを初期化。
ginパッケージをゲット。

```
$ mkdir GinFileupload&& cd GinFileupload
$ go mod init GinFileupload
$ go get -u github.com/gin-gonic/gin
```

そしてmain.goを作成。
フロントはvueだが、vueと絡めるとリンク先の通りにやっても動かないので以下のようにする。
（ginよりもvueのビルド設定に時間を取られてしまった・・・）

```go:main.go
package main

import (
	"io"
	"log"
	"net/http"
	"os"

	"github.com/gin-gonic/gin"
)

func main() {
	engine := gin.Default()

	engine.Static("/dist", "./dist")

	// htmlのディレクトリを指定
	engine.LoadHTMLGlob("*.html")

	engine.GET("/", func(ctx *gin.Context) {
		ctx.HTML(200, "index.html", gin.H{})
	})

	engine.POST("/upload", func(c *gin.Context) {
		file, header, err := c.Request.FormFile("image")
		if err != nil {
			c.String(http.StatusBadRequest, "Bad request")
			return
		}
		fileName := header.Filename
		dir, _ := os.Getwd()
		out, err := os.Create(dir + "\\images\\" + fileName)
		if err != nil {
			log.Fatal(err)
		}
		defer out.Close()
		_, err = io.Copy(out, file)
		if err != nil {
			log.Fatal(err)
		}
		c.JSON(http.StatusOK, gin.H{
			"status": "ok",
		})
	})
	engine.Run(":3000")

}
```

構成はこんな感じ。
![WS000002 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546752/6579b4c8-2591-423a-faad-44a4e33633aa.jpeg)


vueのビルド設定等々は以下を参照。
https://github.com/yusuke-nomura-cosmoroot/GinFileupload

# まとめ
GET、POSTをわりと簡単に実装できた。
（Vueの準備が整っていれば・・・）
実際の開発でもmain.goで全てのルーティングをやるのだろうか？
今までのjavaとかの感覚だとページごとにファイルが分かれててほしくなるが。
共通的に入れたい処理（filter的なもの）は？
いろいろ気になるけどとりあえず次のFWを触ります。
次はbeego。