Go Validator

Built-in Regex Validator And Custom Validators

Regex Validator

Regex(pattern string)

Validates a string against a regular expression.

Purpose: Validates a string against a regular expression.

Usage: Provide a valid regex pattern as a string.

Example Patterns:

Alphanumeric: ^[A-Za-z0-9]+$

Zip Code (5 digits): ^\d{5}$

Email: ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

Usage Example:

validator.CreateValidator(validator.Regex(`^[A-Za-z0-9]+$`), "Value must contain only alphanumeric characters")

Custom Validators

The go-validator package allows you to define and use custom validators tailored to your specific validation needs. Custom validators are created using the CreateValidator helper function, which takes a validation function and an error message as arguments.

How to Add a Custom Validator

  1. Define the Validation Logic Write a function that implements the ValidatorFunc type. This function should:

    • Accept a value of type interface{}.
    • Return an error if the validation fails, or nil if it passes.
  2. Create the Validator Use the CreateValidator function to wrap your validation logic with a custom error message.

  3. Add the Validator to Your Validation Rules Include the custom validator in the Validators field of a ValidationOption.


Step-by-Step Example

Step 1: Define the Validation Logic

Suppose you want to create a custom validator that ensures a string starts with a specific prefix (e.g., "prefix-").

package main
 
import (
    "errors"
    "strings"
 
    "github.com/kthehatter/go-validator/validator"
)
 
// Custom validation function
func StartsWithPrefix(prefix string) validator.ValidatorFunc {
    return func(value interface{}) error {
        str, ok := value.(string)
        if !ok {
            return errors.New("value is not a string")
        }
        if !strings.HasPrefix(str, prefix) {
            return errors.New("value does not start with the required prefix")
        }
        return nil
    }
}

Step 2: Create the Validator

Use the CreateValidator helper function to create a validator with a custom error message.

// Create a custom validator for strings starting with "prefix-"
startsWithPrefixValidator := validator.CreateValidator(
    StartsWithPrefix("prefix-"),
    "The value must start with 'prefix-'",
)

Step 3: Add the Validator to Your Validation Rules

Include the custom validator in the Validators field of a ValidationOption.

validationOptions := []validator.ValidationOption{
    {
        Key:        "code",
        IsOptional: false,
        Validators: []validator.Validator{
            startsWithPrefixValidator,
        },
    },
}

Step 4: Use the Validator

Pass the validationOptions to the Validate function or use it in a framework adapter like Gin.

body := map[string]interface{}{
    "code": "prefix-12345",
}
 
if err := validator.Validate(body, validationOptions); err != nil {
    fmt.Println("Validation failed:", err)
} else {
    fmt.Println("Validation succeeded!")
}

Explanation of the Code

  1. Custom Validation Function

    • The StartsWithPrefix function is a factory function that returns a ValidatorFunc.
    • It checks if the input value is a string and whether it starts with the specified prefix.
  2. CreateValidator

    • The CreateValidator function wraps the validation logic with a custom error message.
    • This makes it easy to reuse the same validation logic with different error messages.
  3. ValidationOption

    • The Validators field of a ValidationOption accepts a slice of Validator objects.
    • You can include multiple validators for a single field.
  4. Validate Function

    • The Validate function iterates over the ValidationOption rules and applies the validators to the corresponding fields in the request body.

Advanced Example: Combining Multiple Validators

You can combine multiple validators for a single field. For example, ensure that a field is both alphanumeric and starts with a specific prefix.

validationOptions := []validator.ValidationOption{
    {
        Key:        "username",
        IsOptional: false,
        Validators: []validator.Validator{
            validator.CreateValidator(validator.IsAlphanumeric, "Username must be alphanumeric"),
            validator.CreateValidator(StartsWithPrefix("user-"), "Username must start with 'user-'"),
        },
    },
}

Tips for Writing Custom Validators

  1. Handle Type Assertions Carefully

    • Always check the type of the input value using type assertions (value.(type)).
    • Return an appropriate error if the value is not of the expected type.
  2. Keep Validators Focused

    • Each validator should focus on a single validation rule. This makes them reusable and easier to test.
  3. Provide Clear Error Messages

    • Use descriptive error messages that explain why the validation failed.
  4. Test Your Validators

    • Write unit tests for your custom validators to ensure they work as expected.

By following these steps, you can easily extend the functionality of the go-validator package with your own custom validation rules.

On this page