1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/gookit-validate

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.zh-CN.md 32 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 27.11.2024 23:39 e7656a2

Валидация

GitHub tag (latest SemVer) GoDoc Build Status Coverage Status Go Report Card Actions Status

Go-библиотека для валидации и фильтрации данных, простая в использовании, со встроенным большинством часто используемых валидаторов и фильтров, с поддержкой пользовательских сообщений и перевода полей.

  • Простота и удобство: поддержка предварительной проверки, возможность добавления пользовательских валидаторов. Большинство фильтров и валидаторов имеют псевдонимы для удобства использования.
  • Поддержка валидации:
    • данных типа Map, Struct, Request (Form, JSON, url.Values, UploadedFile);
    • быстрой настройки правил и валидации данных Map;
    • быстрого валидирования http.Request на основе типа запроса Content-Type и сбора данных;
    • проверки каждого элемента slice. Например: v.StringRule("tags.*", "required|string|minlen:1").
  • Группировка правил по сценариям: разные сценарии могут иметь разные наборы валидируемых полей. В библиотеке уже есть более 70 встроенных валидаторов (см. раздел «Встроенные валидаторы»).
  • Фильтрация перед валидацией: встроенные фильтры (более 20) позволяют адаптировать библиотеку к различным сценариям.
  • Получение информации об ошибках: после валидации можно получить безопасные данные, содержащие только проверенные значения.
  • Пользовательские сообщения об ошибках: можно настроить сообщения об ошибках для каждого валидатора, а также перевод полей и сообщений (встроенные en, zh-CN, zh-TW).
  • Использование в различных фреймворках: библиотека может быть использована в таких фреймворках, как Gin, Echo, Chi и других.
  • Прямое использование правил: правила можно использовать напрямую для проверки значений, например: validate.Val("xyz@mail.com", "required|email").
  • Полноценное модульное тестирование: покрытие тестами более 90%.

Проект вдохновлён такими проектами, как albrow/forms, asaskevich/govalidator и inhere/php-validate. Авторы выражают им свою благодарность.

English

Пожалуйста, ознакомьтесь с введением на английском языке README.

Go Doc

Валидация структур (Struct)

Добавьте тег validate к структуре, чтобы быстро настроить валидацию для этой структуры.

Использование тегов для быстрой настройки валидации

Можно комбинировать теги message и label для быстрой настройки перевода полей структуры и сообщений об ошибках.

  • Поддержка вывода имён полей через структуру с помощью метки json.
  • Поддержка настройки сообщений об ошибках через метку message структуры.
  • Поддержка отображения/перевода полей через метку label структуры.

Пример кода:

package main

import (
    "fmt"
    "time"

    "github.com/gookit/validate"
)

// UserForm struct
type UserForm struct {
    Name     string    `validate:"required|min_len:7" message:"required:{field} is required" label:"用户名称"`
    Email    string    `validate:"email" message:"email is invalid" label:"用户邮箱"`
    Age      int       `validate:"required|int|min:1|max:99" message:"int:age must int|min:age min value is 1"`
    CreateAt int       `validate:"min:1"`
    Safe     int       `validate:"-"` // 标记字段安全无需验证
    UpdateAt time.Time `validate:"required" message:"update time is required"`
    Code     string    `validate:"customValidator"`
    // 结构体嵌套
    ExtInfo struct{
        Homepage string `validate:"required" label:"用户主页"`
        CityName string
    } `validate:"required" label:"扩展信息"`
}

// CustomValidator custom validator in the source struct.
func (f UserForm) CustomValidator(val string) bool {
    return len(val) == 4
}

Настройка валидации через методы структуры

Структуры могут реализовывать три метода интерфейса для дополнительной настройки:

  • ConfigValidation(v *Validation) — вызывается после создания экземпляра валидатора.
  • Messages() map[string]string — позволяет настраивать сообщения об ошибках валидатора.
  • Translates() map[string]string — позволяет настраивать отображение/перевод полей.

Пример кода:

package main

import (
    "fmt"
    "time"

    "github.com/gookit/validate"
)

// UserForm struct
type UserForm struct {
    Name     string    `validate:"required|minLen:7"`
    Email    string    `validate:"email"`
    Age      int       `validate:"required|int|min:1|max:99"`
    Safe     int       `validate:"-"`
    CreateAt int       `validate:"min:1"`
    UpdateAt time.Time `validate:"required"`
    Code     string    `validate:"customValidator"` // 使用自定义验证器
    // 结构体嵌套
    ExtInfo  struct{
        Homepage string `validate:"required"`
        CityName string
    } `validate:"required"`
}

// CustomValidator 定义在结构体中的自定义验证器
func (f UserForm) CustomValidator(val string) bool {

...
} ```
return len(val) == 4
}

// ConfigValidation 配置验证
// - 定义验证场景
// - 也可以添加验证设置
func (f UserForm) ConfigValidation(v *validate.Validation) {
    // v.StringRule()
    
    v.WithScenes(validate.SValues{
        "add":    []string{"ExtInfo.Homepage", "Name", "Code"},
        "update": []string{"ExtInfo.CityName", "Name"},
    })
}

// Messages 您可以自定义验证器错误消息
func (f UserForm) Messages() map[string]string {
    return validate.MS{
        "required": "oh! the {field} is required",
        "Name.required": "message for special field",
    }
}

// Translates 你可以自定义字段翻译
func (f UserForm) Translates() map[string]string {
    return validate.MS{
        "Name": "用户名称",
        "Email": "用户邮箱",
        "ExtInfo.Homepage": "用户主页",
    }
}```

### Создание и вызов проверки

```go
func main() {
    u := &UserForm{
        Name: "inhere",
    }
    
    // 创建 Validation 实例
    v := validate.Struct(u)
    // 或者使用
    // v := validate.New(u)

    if v.Validate() { // 验证成功
        // do something ...
    } else {
        fmt.Println(v.Errors) // 所有的错误消息
        fmt.Println(v.Errors.One()) // 返回随机一条错误消息
        fmt.Println(v.Errors.Field("Name")) // 返回该字段的错误消息
    }
}

Проверка Map данных

package main

import "fmt"
import "github.com/gookit/validate"

func main()  {
    m := map[string]interface{}{
        "name":  "inhere",
        "age":   100,
        "oldSt": 1,
        "newSt": 2,
        "email": "some@email.com",
    }

    v := validate.Map(m)
    // v := validate.New(m)
    v.AddRule("name", "required")
    v.AddRule("name", "minLen", 7)
    v.AddRule("age", "max", 99)
    v.AddRule("age", "min", 1)
    v.AddRule("email", "email")
    
    // 也可以这样,一次添加多个验证器
    v.StringRule("age", "required|int|min:1|max:99")
    v.StringRule("name", "required|minLen:7")
    // feat: 支持在 slice 中检查子项的值
    v.StringRule("tags.*", "required|string|min_len:7")

    // 设置不同场景验证不同的字段
    // v.WithScenes(map[string]string{
    //   "create": []string{"name", "email"},
    //   "update": []string{"name"},
    // })
    
    if v.Validate() { // validate ok
        // do something ...
    } else {
        fmt.Println(v.Errors) // all error messages
        fmt.Println(v.Errors.One()) // returns a random error message text
    }
}

Проверка запроса

Передать в *http.Request, быстрый метод FromRequest() автоматически соберёт соответствующие данные на основе метода запроса и типа данных запроса.

  • GET/DELETE/... и т. д., будет собирать данные URL query
  • POST/PUT/PATCH и тип application/json будет собирать данные JSON
  • POST/PUT/PATCH и тип multipart/form-data будет собирать данные формы, а также данные загрузки файлов
  • POST/PUT/PATCH и тип application/x-www-form-urlencoded будет собирать данные формы
package main

import (
    "fmt"
    "net/http"

    "github.com/gookit/validate"
)

func main()  {
    handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        data, err := validate.FromRequest(r)
        if err != nil {
            panic(err)
        }
        
        v := data.Create()
        // setting rules
        v.FilterRule("age", "int") // convert value to int
        
        v.AddRule("name", "required")
        v.AddRule("name", "minLen", 7)
        v.AddRule("age", "max", 99)
        
        if v.Validate() { // validate ok
            // do something ...
        } else {
            fmt.Println(v.Errors) // all error messages
            fmt.Println(v.Errors.One()) // returns a random error message text
        }
    })
    
    http.ListenAndServe(":8090", handler)
}

Часто используемые методы

Быстро создать экземпляр Validation:

  • Request(r *http.Request) *Validation
  • JSON(s string, scene ...string) *Validation
  • Struct(s interface{}, scene ...string) *Validation
  • Map(m map[string]interface{}, scene ...string) *Validation
  • New(data interface{}, scene ...string) *Validation

Быстро создайте экземпляр DataFace:

  • FromMap(m map[string]interface{}) *MapData
  • FromStruct(s interface{}) (*StructData, error)
  • FromJSON(s string) (*MapData, error)
  • FromJSONBytes(bs []byte) (*MapData, error)
  • FromURLValues(values url.Values) *FormData
  • FromRequest(r *http.Request, maxMemoryLimit ...int64) (DataFace, error) Проверка (Validation) в Go: методы, ошибки и глобальные настройки

Методы:

  • AtScene(scene string) *Validation — устанавливает текущее имя сценария проверки.
  • Filtering() bool — применяет все правила фильтрации.
  • Validate() bool — применяет все правила проверки и фильтрации, возвращает успешность проверки.
  • ValidateE() Errors — применяет все правила проверки и фильтрации и возвращает ошибку при неудаче.
  • SafeData() map[string]interface{} — получает все проверенные данные.
  • BindSafeData(ptr interface{}) error — привязывает проверенные данные к структуре.

Ошибки: v.Errors — это карта данных, где ключ — это имя поля, а значение — map[string]string.

Пример проверки:

// do validating
if v.Validate() {
    return nil
}

// get errors
es := v.Errors

// check
es.Empty() // bool

// возвращает случайную ошибку, если ошибок нет, то возвращает nil
fmt.Println(v.Errors.OneError())
fmt.Println(v.Errors.ErrOrNil())

fmt.Println(v.Errors) // все сообщения об ошибках
fmt.Println(v.Errors.One()) // возвращает случайное сообщение об ошибке
fmt.Println(v.Errors.Field("Name")) // возвращает сообщения об ошибках для поля

JSON-ошибки:

  • StopOnError=true (по умолчанию) — будет только одна ошибка:
{
    "field1": {
        "required": "error msg0"
    }
}
  • StopOnError=false — может быть несколько ошибок:
{
    "field1": {
        "minLen": "error msg1",
        "required": "error msg0"
    },
    "field2": {
        "min": "error msg2"
    }
}

Глобальные опции: Вы можете изменить логику обработки валидатора, изменив глобальные параметры.

// GlobalOption settings for validate
type GlobalOption struct {
    // FilterTag 结构体中的过滤规则标签名称。默认 'filter`
    FilterTag string
    // ValidateTag 结构体中的验证规则标签名称。默认 'validate`
    ValidateTag string
    // FieldTag 定义结构体字段验证错误时的输出名字。默认使用 json
    FieldTag string
    // LabelTag 定义структура поля проверки ошибок времени перевода имени。默认使用 label
    // - 等同于设置 字段 translate
    LabelTag string
    // MessageTag define error message for the field. default: message
    MessageTag string
    // StopOnError 如果为 true,则出现第一个错误时,将停止继续验证。默认 true
    StopOnError bool
    // SkipOnEmpty 跳过对字段不存在或值为空的检查。默认 true
    SkipOnEmpty bool
    // UpdateSource Whether to update source field value, useful for struct validate
    UpdateSource bool
    // CheckDefault Whether to validate the default value set by the user
    CheckDefault bool
    // CheckZero Whether validate the default zero value. (intX,uintX: 0, string: "")
    CheckZero bool
    // CheckSubOnParentMarked 当字段是一个结构体时,仅在当前字段配置了验证tag时才收集子结构体的规则
    CheckSubOnParentMarked bool
}

Настройка:

    // 更改全局选项
    validate.Config(func(opt *validate.GlobalOption) {
        opt.StopOnError = false
        opt.SkipOnEmpty = false
    })

Пользовательские сообщения об ошибках:

  • Регистрация встроенных языковых сообщений:
import "github.com/gookit/validate/locales/zhcn"

// for all Validation.
// NOTICE: 必须在调用 validate.New() 前注册, 它只需要一次调用。
zhcn.RegisterGlobal()

// ... ...

v := validate.New()

// only for current Validation
zhcn.Register(v)
  • Добавление глобальных сообщений вручную:
validate.AddGlobalMessages(map[string]string{
    "minLength": "OO! {field} min length is %d",
})
  • Для текущего подтверждения добавьте сообщения (только для текущей проверки):
v := validate.New(map[string]interface{}{
    "name": "inhere",
})
v.StringRule("name", "required|string|minLen:7|maxLen:15")

v.AddMessages(map[string]string{
    "minLength": "OO! {field} min length is %d",
    "name.minLen": "OO! username min length is %d",
})
  • Использование тегов структуры: message, label:
type UserForm struct {
    Name     string    `validate:"required|minLen:7" label:"用户名称"`
    Email    string    `validate:"email" message:"email is invalid" label:"用户邮箱"`
}
  • Структура может использовать метод Messages() для добавления:
// Messages you can custom validator error messages. 
func (f UserForm) Messages() map[string]string {
    return validate.MS{
        "required": "oh! the {field} is required",
        "Name.required": "message for special field",
    }
}

Создание пользовательских валидаторов: validate поддерживает добавление пользовательских валидаторов, и поддерживает добавление глобальных и временных валидаторов.

  • Глобальный валидатор действует глобально, после регистрации его можно использовать везде.
  • Временный валидатор добавляется к текущему экземпляру проверки, используется только при текущей проверке.

В структуре можно добавить метод проверки. Пример использования см. в примере структуры выше func (f UserForm) CustomValidator(val string) bool.

Обратите внимание: метод валидатора должен возвращать логическое значение, указывающее на успешность валидации. Первый параметр — это соответствующее значение поля, дополнительные параметры добавляются автоматически. ``` myCheck1: func(val interface{}) bool { // do validate val ... return true }, )


#### Добавление временных валидаторов

Также можно добавить один или несколько пользовательских валидаторов за один раз.

```go
v := validate.Struct(u)
v.AddValidator("myFunc3", func(val interface{}) bool {
    // do validate val ...
    return true
})
v.AddValidators(M{
    "myFunc4": func(val interface{}) bool {
        // do validate val ...
        return true
    },
})

Добавление пользовательских фильтров

validate также позволяет добавлять пользовательские фильтры, поддерживая как глобальные, так и временные фильтры двух типов.

  • Глобальный фильтр действует глобально, становится активным после регистрации.
  • Временный фильтр добавляется к текущему экземпляру проверки, доступен только во время текущей проверки.

TIP: Для функций фильтра допускается наличие одного возвращаемого значения inteface{} или двух возвращаемых значений (inteface{},error), где второе может возвращать ошибку.

Добавление глобального фильтра

Можно добавить один или несколько глобальных фильтров за один раз.

package main

import "github.com/gookit/validate"

func init() {
    validate.AddFilter("myToIntFilter0", func(val interface{}) int {
        // do filtering val ...
        return 1
    })
    validate.AddFilters(validate.M{
        "myToIntFilter1": func(val interface{}) (int, error) {
            // do filtering val ...
            return 1, nil
        },
    })
}

Добавление временного фильтра

Аналогично можно добавить один или несколько временных фильтров за один раз.

package main

import "github.com/gookit/validate"

func main() {
    v := validate.New(&someStrcut{})

    v.AddFilter("myToIntFilter0", func(val interface{}) int {
        // do filtering val ...
        return 1
    })
    v.AddFilters(validate.M{
        "myToIntFilter1": func(val interface{}) (int, error) {
            // do filtering val ...
            return 1, nil
        },
    })
}

Пользовательский валидатор required

Позволяет создавать пользовательские валидаторы required для индивидуальной проверки на пустоту. Однако следует отметить, что имя валидатора должно начинаться с required, например required_custom.

type Data struct {
    Age  int    `validate:"required_custom" message:"age is required"`
    Name string `validate:"required"`
}

v := validate.New(&Data{
    Name: "tom",
    Age:  0,
})

v.AddValidator("required_custom", func(val interface{}) bool {
    // do check value
    return false
})

ok := v.Validate()
assert.False(t, ok)

Использование в фреймворке gin

В любом фреймворке можно использовать validate, включая Gin, Echo, Chi и другие. Здесь приведён пример использования с Gin.

package main
import (
    "github.com/gin-gonic/gin/binding"
    "github.com/gookit/validate"
)

// implements the binding.StructValidator
type customValidator struct {}

func (c *customValidator) ValidateStruct(ptr interface{}) error {
    v := validate.Struct(ptr)
    v.Validate() // 调用验证

    return v.Errors
}

func (c *customValidator) Engine() interface{} {
    return nil
}

func main()  {
    // ...

    // after init gin, set custom validator
    binding.Validator = &customValidator{}
}

Встроенные валидаторы

Несколько основных категорий:

  • (Обязательное) обязательное поле
  • Тип проверки
  • Проверка размера и длины
  • Сравнение значений полей
  • Файловая проверка
  • Дата проверки
  • Строковая проверка
  • Другие проверки

TIP: Все верблюжьи имена валидаторов теперь имеют добавленные псевдонимы в нижнем регистре. Таким образом, endsWith также можно записать как ends_with.

Валидатор/псевдоним Описание
required Поле обязательно, значение не может быть пустым
required_if/requiredIf required_if:anotherfield,value,... Если другое поле anotherField имеет любое из значений value, то это поле проверки должно существовать и не быть пустым.
required_unless/requiredUnless required_unless:anotherfield,value,... Если другое поле не равно любому из значений, то это поле проверки должно существовать и не быть пустым.
required_with/requiredWith required_with:foo,bar,... Только когда другие указанные поля присутствуют, поле проверки должно существовать и быть непустым.
required_with_all/requiredWithAll required_with_all:foo,bar,... Поле проверки должно существовать и быть непустым только тогда, когда все указанные поля присутствуют.
required_without/requiredWithout required_without:foo,bar,... Когда другие указанные поля отсутствуют, поле проверки должно существовать и быть непустым.
required_without_all/requiredWithoutAll required_without_all:foo,bar,... Поле проверки должно существовать и быть непустым, только когда все указанные поля отсутствуют.
-/safe Помечает текущее поле как безопасное, без необходимости проверки
int/integer/isInt Проверяет, является ли значение intX или uintX, одновременно поддерживая проверку размера "int" "int:2" "int:2,12"
uint/isUint Проверяет, является ли значение uintX (значение >= 0).
bool/isBool Проверяет, является ли значение булевой строкой (true: "1", "on", "yes", "true", false: "0", "off", "no", "false").
string/isString Проверяет, является ли значение строковым, одновременно поддерживая длину проверки "string" "string:2" "string:2,12"
float/isFloat Проверяет, является ли значение float(floatX)
slice/isSlice Проверяет, является ли значение slice ([]intX []uintX []byte []string и т.д.).
in/enum Проверяет, находится ли значение в заданном списке перечислений ([]string, []intX, []uintX) Инструменты Gookit

off, no, false) trim/trimSpace | Очистить строку от пробельных символов с обеих сторон ltrim/trimLeft | Очистить строку от пробельных символов слева rtrim/trimRight | Очистить строку от пробельных символов справа int/integer | Преобразовать значение (строка / intX / floatX) в тип int v.FilterRule("id", "int") lower/lowercase | Перевести строку в нижний регистр upper/uppercase | Перевести строку в верхний регистр lcFirst/lowerFirst | Сделать первый символ строки строчным ucFirst/upperFirst | Сделать первый символ строки прописным ucWord/upperWord | Сделать первые символы слов прописными camel/camelCase | Привести строку к стилю именования Camel snake/snakeCase | Привести строку к стилю именования Snake escapeJs/escapeJS | Экранировать строку JS escapeHtml/escapeHTML | Экранировать HTML-строку str2ints/strToInts | Конвертировать строку в срез int []int str2time/strToTime | Конвертировать дату в строку формата time.Time str2arr/str2array/strToArray | Конвертировать строку в массив строк []string

Добро пожаловать в Star

Инструменты Gookit

Gookit предоставляет набор инструментов для разработки на Go. Вот некоторые из них:

  • gookit/ini — INI-конфигурация для чтения и управления, поддерживает загрузку нескольких файлов, объединение данных, анализ переменных ENV и переменных ссылок.
  • gookit/rux — простой и быстрый маршрутизатор запросов для HTTP на Golang.
  • gookit/gcli — набор инструментов командной строки для Golang, включая выполнение команд CLI, поддержку цвета в командной строке, взаимодействие с пользователем, отображение прогресса и форматирование данных.
  • gookit/event — легковесная библиотека управления событиями и планирования для Golang, которая позволяет устанавливать приоритеты для слушателей событий и отслеживать группы событий.
  • gookit/cache — универсальная библиотека кэширования, предоставляющая унифицированный API через оболочку различных популярных драйверов кэша.
  • gookit/config — управление конфигурацией приложений Golang, поддерживающее несколько форматов (JSON, YAML, TOML, INI, HCL, ENV, Flags), загрузку нескольких файлов и удаленную загрузку файлов, а также объединение данных.
  • gookit/color — библиотека для рендеринга цветов в консоли CLI, предлагающая простой API и поддержку 16 цветов, 256 цветов и рендеринг RGB.
  • gookit/filter — предоставляет фильтрацию и очистку данных Golang.
  • gookit/validate — общая библиотека проверки и фильтрации данных для Golang с простым использованием и встроенной поддержкой большинства распространённых проверок и фильтров.
  • gookit/goutil — некоторые инструменты Golang, такие как форматирование, специальная обработка, получение общей информации и т. д.

Для получения дополнительной информации посетите страницу https://github.com/gookit.

Проекты для сравнения

Лицензия

MIT

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/gookit-validate.git
git@api.gitlife.ru:oschina-mirror/gookit-validate.git
oschina-mirror
gookit-validate
gookit-validate
master