Is there a more elegant way to validate json body and route id using go-gin?
package controllers
import (
"giin/inputs"
"net/http"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
func GetAccount(context *gin.Context) {
// validate if `accountId` is valid `uuid``
_, err := uuid.Parse(context.Param("accountId"))
if err != nil {
context.JSON(http.StatusBadRequest, gin.H{"message": err.Error()})
return
}
// some logic here...
context.JSON(http.StatusOK, gin.H{"message": "account received"})
}
func AddAccount(context *gin.Context) {
// validate if `body` is valid `inputs.Account`
var input inputs.Account
if error := context.ShouldBindJSON(&input); error != nil {
context.JSON(http.StatusBadRequest, error.Error())
return
}
// some logic here...
context.JSON(http.StatusOK, gin.H{"message": "account added"})
}
I created middleware which is able to detect if accountId was passed and if yes validate it and return bad request if accountId was not in uuid format but I couldn't do the same with the body because AccountBodyMiddleware tries to validate every request, could someone help me with this?
And also it would be nice if I could validate any type of body instead creating new middleware for each json body
package main
import (
"giin/controllers"
"giin/inputs"
"net/http"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
func AccountIdMiddleware(c *gin.Context) {
id := c.Param("accountId")
if id == "" {
c.Next()
return
}
if _, err := uuid.Parse(id); err != nil {
c.JSON(http.StatusBadRequest, "uuid not valid")
c.Abort()
return
}
}
func AccountBodyMiddleware(c *gin.Context) {
var input inputs.Account
if error := c.ShouldBindJSON(&input); error != nil {
c.JSON(http.StatusBadRequest, "body is not valid")
c.Abort()
return
}
c.Next()
}
func main() {
r := gin.Default()
r.Use(AccountIdMiddleware)
r.Use(AccountBodyMiddleware)
r.GET("/account/:accountId", controllers.GetAccount)
r.POST("/account", controllers.AddAccount)
r.Run(":5000")
}