Skip to content

Commit 0e70fdf

Browse files
Dean KarnDean Karn
authored andcommitted
add translation example + documentation
1 parent a7ca4a1 commit 0e70fdf

File tree

2 files changed

+82
-320
lines changed

2 files changed

+82
-320
lines changed

README.md

Lines changed: 6 additions & 272 deletions
Original file line numberDiff line numberDiff line change
@@ -56,278 +56,12 @@ Please see http://godoc.org/gopkg.in/go-playground/validator.v9 for detailed usa
5656

5757
##### Examples:
5858

59-
Struct & Field validation
60-
```go
61-
package main
62-
63-
import (
64-
"fmt"
65-
66-
"gopkg.in/go-playground/validator.v9"
67-
)
68-
69-
// User contains user information
70-
type User struct {
71-
FirstName string `validate:"required"`
72-
LastName string `validate:"required"`
73-
Age uint8 `validate:"gte=0,lte=130"`
74-
Email string `validate:"required,email"`
75-
FavouriteColor string `validate:"iscolor"` // alias for 'hexcolor|rgb|rgba|hsl|hsla'
76-
Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
77-
}
78-
79-
// Address houses a users address information
80-
type Address struct {
81-
Street string `validate:"required"`
82-
City string `validate:"required"`
83-
Planet string `validate:"required"`
84-
Phone string `validate:"required"`
85-
}
86-
87-
// use a single instance of Validate, it caches struct info
88-
var validate *validator.Validate
89-
90-
func main() {
91-
92-
validate = validator.New()
93-
94-
validateStruct()
95-
validateVariable()
96-
}
97-
98-
func validateStruct() {
99-
100-
address := &Address{
101-
Street: "Eavesdown Docks",
102-
Planet: "Persphone",
103-
Phone: "none",
104-
}
105-
106-
user := &User{
107-
FirstName: "Badger",
108-
LastName: "Smith",
109-
Age: 135,
110-
111-
FavouriteColor: "#000-",
112-
Addresses: []*Address{address},
113-
}
114-
115-
// returns nil or ValidationErrors ( map[string]*FieldError )
116-
err := validate.Struct(user)
117-
if err != nil {
118-
119-
// this check is only needed when your code could produce
120-
// an invalid value for validation such as interface with nil
121-
// value most including myself do not usually have code like this.
122-
if _, ok := err.(*validator.InvalidValidationError); ok {
123-
fmt.Println(err)
124-
return
125-
}
126-
127-
for _, err := range err.(validator.ValidationErrors) {
128-
129-
fmt.Println(err.Namespace())
130-
fmt.Println(err.Field())
131-
fmt.Println(err.StructNamespace()) // can differ when a custom TagNameFunc is registered or
132-
fmt.Println(err.StructField()) // by passing alt name to ReportError like below
133-
fmt.Println(err.Tag())
134-
fmt.Println(err.ActualTag())
135-
fmt.Println(err.Kind())
136-
fmt.Println(err.Type())
137-
fmt.Println(err.Value())
138-
fmt.Println(err.Param())
139-
fmt.Println()
140-
}
141-
142-
// from here you can create your own error messages in whatever language you wish
143-
return
144-
}
145-
146-
// save user to database
147-
}
148-
149-
func validateVariable() {
150-
151-
myEmail := "joeybloggs.gmail.com"
152-
153-
errs := validate.Var(myEmail, "required,email")
154-
155-
if errs != nil {
156-
fmt.Println(errs) // output: Key: "" Error:Field validation for "" failed on the "email" tag
157-
return
158-
}
159-
160-
// email ok, move on
161-
}
162-
```
163-
164-
Custom Field Type
165-
```go
166-
package main
167-
168-
import (
169-
"database/sql"
170-
"database/sql/driver"
171-
"fmt"
172-
"reflect"
173-
174-
"gopkg.in/go-playground/validator.v9"
175-
)
176-
177-
// DbBackedUser User struct
178-
type DbBackedUser struct {
179-
Name sql.NullString `validate:"required"`
180-
Age sql.NullInt64 `validate:"required"`
181-
}
182-
183-
// use a single instance of Validate, it caches struct info
184-
var validate *validator.Validate
185-
186-
func main() {
187-
188-
validate = validator.New()
189-
190-
// register all sql.Null* types to use the ValidateValuer CustomTypeFunc
191-
validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})
192-
193-
// build object for validation
194-
x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}}
195-
196-
err := validate.Struct(x)
197-
198-
if err != nil {
199-
fmt.Printf("Err(s):\n%+v\n", err)
200-
}
201-
}
202-
203-
// ValidateValuer implements validator.CustomTypeFunc
204-
func ValidateValuer(field reflect.Value) interface{} {
205-
206-
if valuer, ok := field.Interface().(driver.Valuer); ok {
207-
208-
val, err := valuer.Value()
209-
if err == nil {
210-
return val
211-
}
212-
// handle the error how you want
213-
}
214-
215-
return nil
216-
}
217-
```
218-
219-
Struct Level Validation
220-
```go
221-
package main
222-
223-
import (
224-
"fmt"
225-
226-
"gopkg.in/go-playground/validator.v9"
227-
)
228-
229-
// User contains user information
230-
type User struct {
231-
FirstName string `json:"fname"`
232-
LastName string `json:"lname"`
233-
Age uint8 `validate:"gte=0,lte=130"`
234-
Email string `validate:"required,email"`
235-
FavouriteColor string `validate:"hexcolor|rgb|rgba"`
236-
Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
237-
}
238-
239-
// Address houses a users address information
240-
type Address struct {
241-
Street string `validate:"required"`
242-
City string `validate:"required"`
243-
Planet string `validate:"required"`
244-
Phone string `validate:"required"`
245-
}
246-
247-
// use a single instance of Validate, it caches struct info
248-
var validate *validator.Validate
249-
250-
func main() {
251-
252-
validate = validator.New()
253-
254-
// register validation for 'User'
255-
// NOTE: only have to register a non-pointer type for 'User', validator
256-
// interanlly dereferences during it's type checks.
257-
validate.RegisterStructValidation(UserStructLevelValidation, User{})
258-
259-
// build 'User' info, normally posted data etc...
260-
address := &Address{
261-
Street: "Eavesdown Docks",
262-
Planet: "Persphone",
263-
Phone: "none",
264-
City: "Unknown",
265-
}
266-
267-
user := &User{
268-
FirstName: "",
269-
LastName: "",
270-
Age: 45,
271-
272-
FavouriteColor: "#000",
273-
Addresses: []*Address{address},
274-
}
275-
276-
// returns InvalidValidationError for bad validation input, nil or ValidationErrors ( []FieldError )
277-
err := validate.Struct(user)
278-
if err != nil {
279-
280-
// this check is only needed when your code could produce
281-
// an invalid value for validation such as interface with nil
282-
// value most including myself do not usually have code like this.
283-
if _, ok := err.(*validator.InvalidValidationError); ok {
284-
fmt.Println(err)
285-
return
286-
}
287-
288-
for _, err := range err.(validator.ValidationErrors) {
289-
290-
fmt.Println(err.Namespace())
291-
fmt.Println(err.Field())
292-
fmt.Println(err.StructNamespace()) // can differ when a custom TagNameFunc is registered or
293-
fmt.Println(err.StructField()) // by passing alt name to ReportError like below
294-
fmt.Println(err.Tag())
295-
fmt.Println(err.ActualTag())
296-
fmt.Println(err.Kind())
297-
fmt.Println(err.Type())
298-
fmt.Println(err.Value())
299-
fmt.Println(err.Param())
300-
fmt.Println()
301-
}
302-
303-
// from here you can create your own error messages in whatever language you wish
304-
return
305-
}
306-
307-
// save user to database
308-
}
309-
310-
// UserStructLevelValidation contains custom struct level validations that don't always
311-
// make sense at the field validation level. For Example this function validates that either
312-
// FirstName or LastName exist; could have done that with a custom field validation but then
313-
// would have had to add it to both fields duplicating the logic + overhead, this way it's
314-
// only validated once.
315-
//
316-
// NOTE: you may ask why wouldn't I just do this outside of validator, because doing this way
317-
// hooks right into validator and you can combine with validation tags and still have a
318-
// common error output format.
319-
func UserStructLevelValidation(sl validator.StructLevel) {
320-
321-
user := sl.Current().Interface().(User)
322-
323-
if len(user.FirstName) == 0 && len(user.LastName) == 0 {
324-
sl.ReportError(user.FirstName, "FirstName", "fname", "fnameorlname", "")
325-
sl.ReportError(user.LastName, "LastName", "lname", "fnameorlname", "")
326-
}
327-
328-
// plus can to more, even with different tag than "fnameorlname"
329-
}
330-
```
59+
- [Simple](https://github.com/go-playground/validator/blob/v9/examples/simple/main.go)
60+
- [Custom Field Types](https://github.com/go-playground/validator/blob/v9/examples/custom/main.go)
61+
- [Struct Level](https://github.com/go-playground/validator/blob/v9/examples/struct-level/main.go)
62+
- [Translations & Custom Errors](https://github.com/go-playground/validator/blob/v9/examples/translations/main.go)
63+
- [Gin upgrade and/or override validator](https://github.com/go-playground/validator/tree/v9/examples/gin-upgrading-overriding)
64+
- [wash - an example application putting it all together](https://github.com/bluesuncorp/wash)
33165

33266
Benchmarks
33367
------

0 commit comments

Comments
 (0)