I've stepped into something I don't understand.
Here is an example of Gin API route handler, written in Golang.
// src/file1.go
func CreateDataModelAction(c *gin.Context) {
var input inputs.CreateDataModelInput
if err := c.ShouldBindJSON(&input); err != nil {
// Here I use a function that generates and returns API responses for validation errors.
// This function is located in separate file and it's going to be listed below this code block.
api.RespondWithValidationError(c, outputs.GetValidationErrors(err))
return
}
c.JSON(http.StatusCreated, nil)
}
// src/file2.go
func RespondWithValidationError(c *gin.Context, validationErrors outputs.DataValidationErrorAPIResponse) {
c.AbortWithStatusJSON(http.StatusUnprocessableEntity, validationErrors)
}
In case of validation errors happening after ShouldBindJSON
I expect this code to enter if
block and to return 422
status code with validation errors. However, this code always returns status code 200
despite the fact thic function can only return 422
or 201
.
But if I remove api.RespondWithValidationError
function and use AbortWithStatusJSON
function directly in route handler, I receive the status code 422
as it is expected.
// This example works as expected
func CreateDataModelAction(c *gin.Context) {
var input inputs.CreateDataModelInput
if err := c.ShouldBindJSON(&input); err != nil {
c.AbortWithStatusJSON(http.StatusUnprocessableEntity)
return
}
c.JSON(http.StatusCreated, nil)
}
I was trying to read Gin context source code in order to understand why this is happening, and I have not succeeded so far.
Please explain to me how exactly Gin context works in this case and why I'm not receiving 422
when I'm returning 422
status code from separate function.