🦔

【go超初心者】ginプロジェクト作成

2024/02/29に公開

この記事のゴール

gin構築してAPIでハローワールドするまで。

追記:↑あまりにも一瞬だった。。。
参考記事の方を読んだ方が賢くなれます。。。

背景

goのキャッチアップとして、バックエンドサーバーを構築したい。
せっかくなのでフレームワークはginを使ってみる。
最終的にはクライアント側も作って何か作ってみようかなと思っている。
バックエンドに関してはLaravel等でrestAPIは作れる程度。
goについては本当に無知です。😇

環境

Mac book air(M1)

  • mac os 14.3

goインストール

brew install go

確認

go version
# go version go1.22.0 darwin/arm64

gin

公式リファレンス:https://gin-gonic.com/ja/
参考記事:https://qiita.com/Syoitu/items/8e7e3215fb7ac9dabc3a

まずはディレクトリに移動する。

cd web/gin

goの初期化。

go mod init github.com/gitHubユーザ名/任意の名前

ginプロジェクトの作成。
プロジェクト名をginProjectとしている。

go get -u github.com/gin-gonic/ginProject

ディレクトリ構成

前提として、Dockerに移行することを見据えている。
今後dbコンテナなども増やすことを考えて、webディレクトリを切っている。
ここまでの作業でginProject以下のディレクトリが生成される。

ProjectRoot/
├──web/
  ├──ginProject/
     ├──go.mod
     ├──go.sum
     ├──main.go
├──README.md

main.go

ginのプロジェクトを作成した段階でもう動く。
ローカルサーバーの起動とルーティングがデフォで書かれている。
すでにAPIのサンプルが実装されている。
go run main.goでファイルを実行した後に、
ブラウザで適当にアクセスしたらGETに対してのレスポンスが返ってくる。

試しにhttp://localhost:8080/user/taroアクセスしたら、
ブラウザに{"status":"no value","user":"taro"}が表示される。

以下はファイルの中身。

package main

import (
	"net/http"

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

var db = make(map[string]string)

func setupRouter() *gin.Engine {
	// Disable Console Color
	// gin.DisableConsoleColor()
	r := gin.Default()

	// Ping test
	r.GET("/ping", func(c *gin.Context) {
		c.String(http.StatusOK, "pong")
	})

	// Get user value
	r.GET("/user/:name", func(c *gin.Context) {
		user := c.Params.ByName("name")
		value, ok := db[user]
		if ok {
			c.JSON(http.StatusOK, gin.H{"user": user, "value": value})
		} else {
			c.JSON(http.StatusOK, gin.H{"user": user, "status": "no value"})
		}
	})

	// Authorized group (uses gin.BasicAuth() middleware)
	// Same than:
	// authorized := r.Group("/")
	// authorized.Use(gin.BasicAuth(gin.Credentials{
	//	  "foo":  "bar",
	//	  "manu": "123",
	//}))
	authorized := r.Group("/", gin.BasicAuth(gin.Accounts{
		"foo":  "bar", // user:foo password:bar
		"manu": "123", // user:manu password:123
	}))

	/* example curl for /admin with basicauth header
	   Zm9vOmJhcg== is base64("foo:bar")

		curl -X POST \
	  	http://localhost:8080/admin \
	  	-H 'authorization: Basic Zm9vOmJhcg==' \
	  	-H 'content-type: application/json' \
	  	-d '{"value":"bar"}'
	*/
	authorized.POST("admin", func(c *gin.Context) {
		user := c.MustGet(gin.AuthUserKey).(string)

		// Parse JSON
		var json struct {
			Value string `json:"value" binding:"required"`
		}

		if c.Bind(&json) == nil {
			db[user] = json.Value
			c.JSON(http.StatusOK, gin.H{"status": "ok"})
		}
	})

	return r
}

func main() {
	r := setupRouter()
	// Listen and Server in 0.0.0.0:8080
	r.Run(":8080")
}

終わりに

あまりにも一瞬だった。
"何もしてないのに"APIサーバーっぽいものはできた(?)が、
"何もしていないので何も理解していない"。
次回はこのデフォのコードを読みながら、goの言語仕様と実行環境を調べていく。
(Docker化はもう少し先か。)

参考記事
https://zenn.dev/soramarjr/articles/5e3898440cd172
https://github.com/golang-standards/project-layout/blob/master/README_ja.md
https://qiita.com/TakanoriVega/items/6d7210147c289b45298a

Discussion