Open5

今更ながらGoのお勉強

lCyoulCyou

API設計する課題で学ぶGo

構造体を書く時

model.go
type HealthzResponse struct{
	Message string `json:"message"`
    Number int `json:",omitempty"`
}

オプションとかでomitemptyとかだと値が入ってなかった時に無視されたり,-だとパースする時に無視させたりできるらしい

lCyoulCyou

今回はnet/httpのみでつくっていく?予定
httpサーバーは大体(1)サーバー立てる(2)エンドポイント作る(3)ハンドラを書くって感じの流れなので順番にこんな感じ?

// (3)
    type Handler struct{}
    func NewHandler() *Handler{
        return &Handler{}
    }
    func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
// (2)
    mux := http.NewServeMux()
    mux.Handle("/endpoint", NewHandler())
// (1)
    server := http.Server{
		Addr: port,
		Handler: mux,
	}

(3)についてはなんでこんなやり方なのかわかっていない
後に調べるとして現在検討ついているのはServeHTTPがHttpHandlerの子だから崩さないように
NewHandlerがいるのか?という感じ

lCyoulCyou

structの埋め込み

structを埋め込んで構造体を再利用できる

type (
	TODO struct{
		ID int `json:"id"`
		Subject string `json:"subject"`
		Description string `json:"description"`
		CreatedAt  time.Time `json:"created_at"`
		UpdatedAt time.Time `json:"updated_at"`
	}

	CreateResponse struct{
		TODO `json:"todo"` 
	}
)
lCyoulCyou

routingは済ませたので,(3)のハンドラについて少し。
たぶんデフォでのルーティングで使うServeMuxとかいうやつはこれだと思う
https://zenn.dev/hsaki/books/golang-httpserver-internal/viewer/httpmux
ぱっと見ではhttp.ServeMuxにもServeHTTPメソッドがあるのでそこで呼ばれる(HandlerメソッドなりMatchメソッドなり)http.ServeMux.handlerで対象のHandlerを扱ってるhttp.HandlerのServeHTTPにメッセージ?かも

handler.go
// ハンドラで扱いたい構造体を定義
type Handler struct {
	svc *service.Service
}

// http.Handlerを元にHandlerを返しているだけ なんかのコンストラクタ?
func NewHandler(svc *service.Service) *Handler {
	return &Handler{
		svc: svc,
	}
}

// メソッドごとにハンドリングする
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodPost {
            // 処理が入る
	} else if r.Method == http.MethodGet{
            // 処理が入る
        }
}
lCyoulCyou

interface{}という使い方がある。空インターフェースというらしい。
idsはスライスだけどids...で展開ではsql.DB.execContextの引数の型と合致しない。
ids を繰り返し処理をして、空のインタフェース型のスライス []interface{}に値を詰め直し

var ids = []int64{1, 2, 3}
var idInterface = make([]interface{}, len(ids))
for i, id := range ids {
    idInterface[i] = id
}
result, err := s.db.ExecContext(ctx, query, idInterface...)