goflexvalidation

module
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2025 License: MIT

README

GoFlexValidation

A flexible and extensible validation library for Go applications. GoFlexValidation offers a simple yet powerful way to validate data structures with a variety of built-in validation rules and support for custom validation functions. My main goal with this package is to be able to apply validations like the C# FluentValidation library does, but in a simple and easy-to-use way.

Features

  • Type-safe validation: Built with Go's reflection system for type-safe validation
  • Extensible rule system: Easy to add custom validation rules
  • Comprehensive error handling: Detailed error messages with field and rule information
  • Multiple validation types: Support for equality, comparison, emptiness, pattern matching, and length validation
  • Custom validators: Support for custom validation functions
  • Clean API: Simple and intuitive API design

Installation

go get gitlab.com/jsalio/goflexvalidation

Quick Start

Validación de structs (recomendado)
package main

import (
    "fmt"
    "gitlab.com/jsalio/goflexvalidation/engine"
)

type User struct {
    Username string
    Age      int
    Email    string
}

func main() {
    // Crear un validador y agregar reglas
    validator := engine.NewValidator()
    validator.AddRule("Username", engine.ShouldNotEmpty, nil, "Username is required")
    validator.AddRule("Age", engine.ShouldGreaterThan, 18, "Age must be greater than 18")
    validator.AddRule("Email", engine.ShouldMatch, `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$`, "Invalid email format")

    // Datos de prueba
    user := User{
        Username: "john_doe",
        Age:      25,
        Email:    "john@example.com",
    }

    // Validar struct completo
    result := validator.Validate(user)
    if len(result.Errors) == 0 {
        fmt.Println("✅ User passed all validations")
    } else {
        for _, err := range result.Errors {
            fmt.Printf("❌ %s: %s\n", err.Field, err.Message)
        }
    }
}
Validación de mapas (map[string]interface{})
package main

import (
    "fmt"
    "gitlab.com/jsalio/goflexvalidation/engine"
)

func main() {
    // Crear reglas de validación
    validator := engine.NewValidator()
    validator.AddRule(engine.ValidationRule{
            FieldName: "username",
            Rule:      engine.ShouldNotEmpty,
            Expected:  "",
            Message:   stringPtr("Username is required"),
        })
    validator.AddRule(engine.ValidationRule{
            FieldName: "age",
            Rule:      engine.ShouldGreaterThan,
            Expected:  18,
            Message:   stringPtr("Age must be greater than 18"),
        })
    validator.AddRule(engine.ValidationRule{
            FieldName: "email",
            Rule:      engine.ShouldMatch,
            Expected:  `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$`,
            Message:   stringPtr("Invalid email format"),
        })
    }

    // Datos de prueba
    data := map[string]interface{}{
        "username": "john_doe",
        "age":      25,
        "email":    "john@example.com",
    }

    // Validar manualmente cada campo
    result := validator.Validate(user)
    if len(result.Errors) == 0 {
        fmt.Println("✅ User passed all validations")
    } else {
        for _, err := range result.Errors {
            fmt.Printf("❌ %s: %s\n", err.Field, err.Message)
        }
    }
}

func stringPtr(s string) *string {
    return &s
}

Available Validation Rules

Equality Rules
  • ShouldEqual: Validates that a field equals a specific value
  • ShouldNotEqual: Validates that a field does not equal a specific value
Comparison Rules
  • ShouldGreaterThan: Validates that a field is greater than a specific value
  • ShouldGreaterOrEqualThan: Validates that a field is greater than or equal to a specific value
  • ShouldLessThan: Validates that a field is less than a specific value
  • ShouldLessOrEqualThan: Validates that a field is less than or equal to a specific value
Emptiness Rules
  • ShouldEmpty: Validates that a field is empty
  • ShouldNotEmpty: Validates that a field is not empty
Pattern Matching Rules
  • ShouldMatch: Validates that a field matches a specific regex pattern
  • ShouldNotMatch: Validates that a field does not match a specific regex pattern
Length Rules
  • ShouldLength: Validates that a field has a specific length
  • ShouldMinLength: Validates that a field has a minimum length
Custom Rules
  • Must: Validates using a custom validation function

Usage Examples

Basic Validation
rule := engine.ValidationRule{
    FieldName: "name",
    Rule:      engine.ShouldNotEmpty,
    Expected:  "",
    Message:   stringPtr("Name is required"),
}

err := rule.Validate("")
if err != nil {
    fmt.Println(err.Message) // Output: Name is required
}
Numeric Validation
rule := engine.ValidationRule{
    FieldName: "score",
    Rule:      engine.ShouldGreaterThan,
    Expected:  0,
    Message:   stringPtr("Score must be positive"),
}

err := rule.Validate(10)
if err != nil {
    fmt.Println(err.Message)
}
Pattern Matching
rule := engine.ValidationRule{
    FieldName: "phone",
    Rule:      engine.ShouldMatch,
    Expected:  `^\d{3}-\d{3}-\d{4}$`,
    Message:   stringPtr("Phone number must be in format XXX-XXX-XXXX"),
}

err := rule.Validate("123-456-7890")
if err != nil {
    fmt.Println(err.Message)
}
Length Validation
rule := engine.ValidationRule{
    FieldName: "password",
    Rule:      engine.ShouldMinLength,
    Expected:  8,
    Message:   stringPtr("Password must be at least 8 characters long"),
}

err := rule.Validate("short")
if err != nil {
    fmt.Println(err.Message) // Output: Password must be at least 8 characters long
}
Custom Validation
// Define custom validation function
func validateEvenNumber(value interface{}) (bool, string) {
    if v, ok := value.(int); ok {
        if v%2 == 0 {
            return true, ""
        }
        return false, "Number must be even"
    }
    return false, "Value must be an integer"
}

// Create custom validation rule
rule := engine.ValidationRule{
    FieldName: "number",
    Rule:      engine.Must,
    Expected:  validateEvenNumber,
    Message:   stringPtr("Invalid number"),
}

err := rule.Validate(7)
if err != nil {
    fmt.Println(err.Message) // Output: Invalid number
}

CI/CD Pipeline

This project includes a comprehensive CI/CD pipeline that supports both GitHub Actions and GitLab CI/CD. The pipeline runs on every push and merge request to the main and develop branches.

Pipeline Stages
  1. Lint and Format Check: Runs code linting and formatting checks
  2. Tests: Executes all tests with coverage reporting
  3. Build: Builds the application for multiple platforms
  4. Deploy: Optional deployment stage for releases
GitLab CI/CD

The project includes a .gitlab-ci.yml file that provides:

  • Automated testing with coverage thresholds (80% minimum)
  • Code quality checks with golangci-lint
  • Multi-platform builds (Linux, macOS, Windows)
  • Security vulnerability scanning
  • Coverage reports and build artifacts
  • Manual deployment for tagged releases
GitHub Actions

The project also includes GitHub Actions workflows:

  • .github/workflows/test.yml - Simple test-only workflow
  • .github/workflows/ci.yml - Comprehensive CI/CD pipeline
Running Tests Locally
# Run all tests
make test

# Run tests with coverage
make test-coverage

# Run specific test file
go test -v ./test/rules_test.go

# Run benchmarks
go test -bench=. -benchmem ./test/...
Coverage Requirements

The CI pipeline enforces a minimum test coverage of 80%. Coverage reports are generated and uploaded as artifacts.

Error Handling

The library provides detailed error information through the ValidationError struct:

type ValidationError struct {
    Field            string
    Rule             RuleType
    Message          string
    Exception        error
    ExceptionMessage string
}

Example results


=== Like Validator Examples ===

1. Basic User Validation
------------------------
✅ Valid user passed all validations
❌ Invalid user failed validations (expected):
  - Username: Username must be at least 3 characters
  - Age: User must be at least 18 years old
  - Password: Password must be at least 8 characters

2. Product Validation with Multiple Rules
------------------------------------------
✅ Valid product passed all validations
❌ Invalid product failed validations (expected):
  - Name: Product name must be at least 3 characters
  - Price: Price must be greater than 0
  - Category: Category cannot be 'Unknown'

3. Order Validation
-------------------
✅ Valid order passed all validations
❌ Invalid order failed validations (expected):
  - CustomerID: Customer ID must be positive
  - TotalAmount: Total amount cannot exceed 100000

4. Custom Validation Functions
------------------------------
❌ User failed validation:
  - Password: Password strength validation failed
  - Email: Email domain validation failed
❌ User with weak password and disposable email failed validation (expected):
  - Password: Password strength validation failed
  - Email: Email domain validation failed

5. Complex Validation Scenarios
--------------------------------
Test Case 1:
  ❌ Failed validations:
    - Bio: Bio validation failed
Test Case 2:
  ❌ Failed validations:
    - Age: User must be at least 13 years old
    - Bio: Bio validation failed
Test Case 3:
  ❌ Failed validations:
    - Username: Username must be at least 3 characters
    - Bio: Bio validation failed

6. Error Handling and Results
------------------------------
Total validation errors: 3
Validation errors:
  Error 1:
    Field: Username
    Rule: NotEmpty
    Message: Username is required
    Exception: validation failed
    Exception Message: Field Username must not be empty

  Error 2:
    Field: Email
    Rule: NotEmpty
    Message: Email is required
    Exception: validation failed
    Exception Message: Field Email must not be empty

  Error 3:
    Field: Age
    Rule: GreaterThan
    Message: Age must be positive
    Exception: validation failed
    Exception Message: Field Age must be greater than 0

✅ All validations passed successfully


Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Requirements

  • Go 1.23.9 or higher

Directories

Path Synopsis
Package engine provides validation rule types and logic for data validation.
Package engine provides validation rule types and logic for data validation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL