22
33> a piece of rope or a tyre that protects the side of a boat from knocks
44
5- Fender provides a unified way to validate data and make the errors passable to the frontend e.g. through gotsrpc .
5+ Fender provides a unified way to validate data and on the backend & frontend side .
66
77## Usage
88
9- Fender provides different ways to validate your data.
10-
11- ### struct validation using go-playground validator
9+ ### All
1210
1311``` go
14- package main
15-
16- import (
17- " fmt"
18-
19- " github.com/foomo/fender"
20- )
21-
22- type Test struct {
23- Int int ` validate:"min=1"`
24- Int8 int8 ` validate:"min=1"`
25- Int32 int32 ` validate:"min=1"`
26- Int64 int64 ` validate:"min=1"`
27- UInt uint ` validate:"min=1"`
28- UInt8 uint8 ` validate:"min=1"`
29- UInt32 uint32 ` validate:"min=1"`
30- UInt64 uint64 ` validate:"min=1"`
31- Float32 float32 ` validate:"min=1.5"`
32- Float64 float64 ` validate:"min=1.5"`
33- Bool bool ` validate:"required"`
34- String string ` validate:"required"`
35- }
36-
37- func main () {
38- u := Test{}
39- fendErr , err := fender.Struct (u)
40- if err != nil {
41- panic (" internal error: " + err.Error ())
12+ func ExampleAll () {
13+ err := fender.All (
14+ context.Background (),
15+ fend.Field (" one" , " " , rule.RequiredString , rule.MinString (10 )),
16+ fend.Field (" two" , " " , rule.RequiredString , rule.MinString (10 )),
17+ )
18+ // check for fender error
19+ if fendErr := fender.AsError (err); fendErr != nil {
20+ fmt.Println (err)
21+ } else if err != nil {
22+ panic (err)
4223 }
43- fmt. Println (fendErr) // bool:required;string :required;uInt :min=1;uInt8:min=1;uInt32 :min=1;uInt64:min=1;float32:min=1.5;int:min=1;int8:min=1;int32:min=1;int64:min=1;float64:min=1.5
24+ // Output: one :required:min=10;two:required :min=10
4425}
4526```
4627
47- ### validate by code
28+ ### AllFirst
4829
4930``` go
50- package main
51-
52- import (
53- " fmt"
54-
55- " github.com/foomo/fender"
56- " github.com/foomo/fender/fend"
57- " github.com/foomo/fender/rule"
58- )
59-
60- type Test struct {
61- Int int
62- Int8 int8
63- Int32 int32
64- Int64 int64
65- UInt uint
66- UInt8 uint8
67- UInt32 uint32
68- UInt64 uint64
69- Float32 float32
70- Float64 float64
71- Bool bool
72- String string
73- }
74-
75- func main () {
76- u := Test{}
77- fendErr , err := fender.All (
78- fender.Field (" int" , fend.Int (u.Int , rule.MinInt (1 ))),
79- fender.Field (" int8" , fend.Int8 (u.Int8 , rule.MinInt8 (1 ))),
80- fender.Field (" int32" , fend.Int32 (u.Int32 , rule.MinInt32 (1 ))),
81- fender.Field (" int64" , fend.Int64 (u.Int64 , rule.MinInt64 (1 ))),
82- fender.Field (" uint" , fend.UInt (u.UInt , rule.MinUInt (1 ))),
83- fender.Field (" uint8" , fend.UInt8 (u.UInt8 , rule.MinUInt8 (1 ))),
84- fender.Field (" uint32" , fend.UInt32 (u.UInt32 , rule.MinUInt32 (1 ))),
85- fender.Field (" uint64" , fend.UInt64 (u.UInt64 , rule.MinUInt64 (1 ))),
86- fender.Field (" float32" , fend.Float32 (u.Float32 , rule.MinFloat32 (1.5 ))),
87- fender.Field (" float64" , fend.Float64 (u.Float64 , rule.MinFloat64 (1.5 ))),
88- fender.Field (" bool" , fend.Bool (u.Bool , rule.Bool (true ))),
89- fender.Field (" string" , fend.String (u.String , rule.RequiredString )),
31+ func ExampleAllFirst () {
32+ err := fender.AllFirst (
33+ context.Background (),
34+ fend.Field (" one" , " " , rule.RequiredString , rule.MinString (10 )),
35+ fend.Field (" two" , " " , rule.RequiredString , rule.MinString (10 )),
9036 )
91- if err != nil {
92- panic (" internal error: " + err.Error ())
37+
38+ // check for fender error
39+ if fendErr := fender.AsError (err); fendErr != nil {
40+ fmt.Println (err)
41+ } else if err != nil {
42+ panic (err)
9343 }
94- fmt. Println (fendErr) // uint:min=1;uint64:min=1;float32:min=1.5;int:min=1;int8:min=1;uint8:min=1;uint32:min=1;float64:min=1.5;bool:bool=true;string: required;int32 :min=1;int64:min=1
44+ // Output: one: required:min=10
9545}
9646```
9747
98- ### validate by code and stop on first error
48+ ### First
9949
10050``` go
101- package main
102-
103- import (
104- " fmt"
105-
106- " github.com/foomo/fender"
107- " github.com/foomo/fender/fend"
108- " github.com/foomo/fender/rule"
109- )
110-
111- type Test struct {
112- Int int
113- Int8 int8
114- Int32 int32
115- Int64 int64
116- UInt uint
117- UInt8 uint8
118- UInt32 uint32
119- UInt64 uint64
120- Float32 float32
121- Float64 float64
122- Bool bool
123- String string
51+ func ExampleFirst () {
52+ err := fender.First (
53+ context.Background (),
54+ fend.Field (" one" , " " , rule.RequiredString , rule.MinString (10 )),
55+ fend.Field (" two" , " " , rule.RequiredString , rule.MinString (10 )),
56+ )
57+
58+ // check for fender error
59+ if fendErr := fender.AsError (err); fendErr != nil {
60+ fmt.Println (err)
61+ } else if err != nil {
62+ panic (err)
63+ }
64+ // Output: one:required
12465}
66+ ```
67+
68+ ### Handle errors
12569
126- func main () {
127- u := Test{}
128- fendErr , err := fender.First (
129- fender.Field (" int" , fend.Int (u.Int , rule.MinInt (1 ))),
130- fender.Field (" int8" , fend.Int8 (u.Int8 , rule.MinInt8 (1 ))),
131- fender.Field (" int32" , fend.Int32 (u.Int32 , rule.MinInt32 (1 ))),
132- fender.Field (" int64" , fend.Int64 (u.Int64 , rule.MinInt64 (1 ))),
133- fender.Field (" uint" , fend.UInt (u.UInt , rule.MinUInt (1 ))),
134- fender.Field (" uint8" , fend.UInt8 (u.UInt8 , rule.MinUInt8 (1 ))),
135- fender.Field (" uint32" , fend.UInt32 (u.UInt32 , rule.MinUInt32 (1 ))),
136- fender.Field (" uint64" , fend.UInt64 (u.UInt64 , rule.MinUInt64 (1 ))),
137- fender.Field (" float32" , fend.Float32 (u.Float32 , rule.MinFloat32 (1.5 ))),
138- fender.Field (" float64" , fend.Float64 (u.Float64 , rule.MinFloat64 (1.5 ))),
139- fender.Field (" bool" , fend.Bool (u.Bool , rule.Bool (true ))),
140- fender.Field (" string" , fend.String (u.String , rule.RequiredString )),
70+ ``` go
71+ func ExampleErrors () {
72+ err := fender.All (
73+ context.Background (),
74+ fend.Field (" one" , " " , rule.RequiredString , rule.MinString (10 )),
75+ fend.Field (" two" , " " , rule.RequiredString , rule.MinString (10 )),
14176 )
142- if err != nil {
143- panic (" internal error: " + err.Error ())
77+
78+ // cast fender error
79+ if fenderErr := fender.AsError (err); fenderErr != nil {
80+
81+ // iterate fend errors
82+ for _ , err := range fenderErr.Errors () {
83+
84+ // cast fend error
85+ if fendErr := fend.AsError (err); fendErr != nil {
86+
87+ fmt.Println (fendErr.Name ())
88+
89+ // iterate rule errors
90+ for _ , err := range fendErr.Errors () {
91+
92+ // cast rule error
93+ if ruleErr := rule.AsError (err); ruleErr != nil {
94+ fmt.Println (ruleErr.Error ())
95+ }
96+ }
97+ }
98+ }
99+ } else if err != nil {
100+ panic (err)
144101 }
145- fmt.Println (fendErr) // int:min=1
102+ // Output:
103+ // one
104+ // required
105+ // min=10
106+ // two
107+ // required
108+ // min=10
146109}
147110```
148111
112+ ## Benchmarks
113+
114+ ``` text
115+ go test -bench=. | prettybench
116+ goos: darwin
117+ goarch: arm64
118+ pkg: github.com/foomo/fender
119+ PASS
120+ benchmark iter time/iter
121+ --------- ---- ---------
122+ BenchmarkAll/invalid_reused/fender-10 282154 3771.00 ns/op
123+ BenchmarkAll/invalid_reused/playground-10 678679 1741.00 ns/op
124+ BenchmarkAll/success_new/fender-10 1000000 1026.00 ns/op
125+ BenchmarkAll/success_new/playground-10 1308327 937.60 ns/op
126+ ok github.com/foomo/fender 5.619s
127+ ```
128+
149129## References & alternatives
150130
151131- [ go-playground/validator] ( https://github.com/go-playground/validator )
@@ -158,7 +138,3 @@ Make a pull request...
158138## License
159139
160140Distributed under MIT License, please see license file within the code for more details.
161-
162- ## Notes
163-
164- We'll take another refactoring round as soon as go supports generics
0 commit comments