Data Validation
Input validation in Gleece is simplified through the use of go-playground/validator v10 format.
Gleece passes validation rules to the go-playground/validator
engine during request processing, exposes them in the OpenAPI v3 specification (where supported), and returns a 422 status code if validation fails.
Explore the full validation options in the go-playground/validator documentation.
Validating Struct Fields
Validation rules follow the standard convention of the go-playground
validator.
// @Description User's domicile
type Domicile struct {
Address string `json:"address" validate:"required"`
// @Description The number of the house (must be at least 1)
HouseNumber int `json:"houseNumber" validate:"gte=1"`
}
validate:"required"
ensures theAddress
field is mandatory.validate:"gte=1"
ensures theHouseNumber
field has a value of at least 1.
Validating REST Parameters (Query, Header, etc.)
Validation rules are defined using the validate
annotation option.
// @Description Create a new user
// @Method(POST)
// @Route(/user/{user_name})
// @Path(name, { name: "user_name", validate: "require" }) The user's name
// @Query(email, { validate: "required,email" }) The user's email
// @Body(domicile) The user's domicile info
// @Header(origin, { name: "x-origin" }) The request origin
// @Header(trace) The trace info
// @Response(200) The ID of the newly created user
// @ErrorResponse(500) The error when process failed
// @Security(ApiKeyAuth, { scopes: ["read:users", "write:users"] })
func (ec *UserController) CreateNewUser(email string, name string, domicile Domicile, origin string, trace string) (string, error) {
// Do the logic....
userId := uuid.New()
return userId.String(), nil
}
validate: "required"
in@Path
ensures the path parameter is mandatoryvalidate: "required,email"
in@Query
ensures:- The email query parameter is mandatory
- The value must be in a valid email format
For REST parameters, non-pointer arguments are always considered mandatory, regardless of the
validate
content. Path parameters are always mandatory as per the OpenAPI specification (a missing path results in a404
error).
Enum Validation Limitations
Go type aliases (commonly used for enums) do not have built-in validation to ensure values match the specified enum options. By default, Gleece only validates that the value matches the underlying type of the alias (int, string, etc.).
For enum validation capabilities, please refer to the Enum Validation section in our experimental features documentation.
Validating Response Payloads
By default, Gleece does not validate the responses payloads.
To enable response payload validation, set the validateResponsePayload
field to true
in the routesConfig
section of the configuration file:
{
"routesConfig": {
"validateResponsePayload": true
}
}
When enabled, Gleece validates the response payload against the defined response schema for the route.
If validation fails, Gleece returns a 500
status code with a generic error message.
The response payload validation is only applied to routes with a struct as the defined response type.
Gleece does not return the actual validation error message of the responses to the client to avoid exposing server internals.
It is highly recommended to add an onOutputValidationError
middleware to log or handle the error appropriately.
Custom Validators
Gleece supports custom validators in a manner similar to go-playground/validator
.
Custom validators only affect runtime validation and are not reflected in the OpenAPI specification.
To create a custom validator, implement Gleece's runtime.ValidationFunc
interface and register it using the generated code API's RegisterCustomValidator
function.
package main
import (
"unicode"
"net/http"
gleeceRoutes "<package>"
"github.com/gopher-fleece/runtime"
"github.com/gin-gonic/gin"
)
// Custom validation function to check if a string starts with a letter
func ValidateStartsWithLetter(fl runtime.ValidationFieldLevel) bool {
field := fl.Field().String()
if field == "" {
return false
}
firstChar := rune(field[0])
return unicode.IsLetter(firstChar)
}
func main() {
// Create a default Gin router
router := gin.Default()
// Register the `ValidateStartsWithLetter` custom validator
gleeceRoutes.RegisterCustomValidator("validate_starts_with_letter", ValidateStartsWithLetter)
// Register the routes from the generated code
gleeceRoutes.RegisterRoutes(router)
// Start the server on port 8080
router.Run("127.0.0.1:8080")
}
After registration, the validate_starts_with_letter
validator becomes active across all API requests.