Skip to content

ghkdqhrbals:gin

Hwangbo Gyumin edited this page May 29, 2022 · 3 revisions

Microservices 제어흐름

Request -> Route Parser -> [Optional Middleware] -> Route Handler -> [Optional Middleware] -> Response

Gin router 생성 -> 루트 정의 및 해당 루트 엑세스 시 handler 설정

router := gin.Default() // router 생성

// router.[GET or POST or etc](url string,HANDLER)
// Route handler 정의
router.GET("/accounts/:id",server.getAccount)

" localhost:8080/accounts/의 뒤에 int64로 GET이 들어오면, id로 tagging하고 server의 getAccount를 실행하여라 " 라는 의미임.

type getAccountRequest struct {
	ID int64 `uri:"id" binding:"required,min=1"`
}

getAccount가 http로 오면 서버에서 다음과 같은 형식에 저장할 것이라고 명시한다.

이때, 기본적인 validate를 통해 조건을 정할 수 있다.(ID는 1이상이고, 비어서는 안되며, ctx.ShouldBindUri을 사용하여 req에 저장할 것이기에 uri: 명시)

이는 기본적인 validate방식이며, gin에서 custom 가능하다.

if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
    v.RegisterValidation("currency", validCurrency) // Register Custom Validator {tag, validator.Func}
}

var validCurrency validator.Func = func(fieldLevel validator.FieldLevel) bool {
	// fieldLevel.Field() to get the value of the field
	if currency, ok := fieldLevel.Field().Interface().(string); ok {
		return util.IsSupportedCurrency(currency)
	}
	return false
}

// Constants for all supported currencies
const (
	USD = "USD"
	EUR = "EUR"
	WON = "WON"
)

func IsSupportedCurrency(currency string) bool {
	switch currency {
	case USD, EUR, WON:
		return true
	}
	return false
}

currency를 확인하는 custom validator 생성

type getAccountRequest struct {
	ID int64 `uri:"id" binding:"required,min=1"`
}

func (server *Server) getAccount(ctx *gin.Context) {
	var req getAccountRequest
	if err := ctx.ShouldBindUri(&req); err != nil { // 우리는 이전 tagging된 id를 getAccountRequest ID에 바인딩.
		ctx.JSON(http.StatusBadRequest, errorResponse(err))
		return
	}
	account, err := server.store.GetAccount(ctx, req.ID) // DB 쿼리 트랜젝션 실행
	if err != nil {
		if err == sql.ErrNoRows {
			ctx.JSON(http.StatusNotFound, errorResponse(err))
			return
		}
		ctx.JSON(http.StatusInternalServerError, errorResponse(err))
		return
	}
	ctx.JSON(http.StatusOK, account)
}

Unmarshelling(gin에서 지원) => ShouldBindUri

이는 다양한 방법 존재. ShouldBindJSON, ShouldBindUri, ShouldBindQuery, etc

server의 getAccount는 server.store.GetAccount로 DB 쿼리 및 기타 ERROR 전송