1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: © 2015 LabStack LLC and Echo contributors
// run tests as external package to get real feel for API
package echo_test
import (
"encoding/base64"
"fmt"
"github.com/labstack/echo/v4"
"log"
"net/http"
"net/http/httptest"
)
func ExampleValueBinder_BindErrors() {
// example route function that binds query params to different destinations and returns all bind errors in one go
routeFunc := func(c echo.Context) error {
var opts struct {
Active bool
IDs []int64
}
length := int64(50) // default length is 50
b := echo.QueryParamsBinder(c)
errs := b.Int64("length", &length).
Int64s("ids", &opts.IDs).
Bool("active", &opts.Active).
BindErrors() // returns all errors
if errs != nil {
for _, err := range errs {
bErr := err.(*echo.BindingError)
log.Printf("in case you want to access what field: %s values: %v failed", bErr.Field, bErr.Values)
}
return fmt.Errorf("%v fields failed to bind", len(errs))
}
fmt.Printf("active = %v, length = %v, ids = %v", opts.Active, length, opts.IDs)
return c.JSON(http.StatusOK, opts)
}
e := echo.New()
c := e.NewContext(
httptest.NewRequest(http.MethodGet, "/api/endpoint?active=true&length=25&ids=1&ids=2&ids=3", nil),
httptest.NewRecorder(),
)
_ = routeFunc(c)
// Output: active = true, length = 25, ids = [1 2 3]
}
func ExampleValueBinder_BindError() {
// example route function that binds query params to different destinations and stops binding on first bind error
failFastRouteFunc := func(c echo.Context) error {
var opts struct {
Active bool
IDs []int64
}
length := int64(50) // default length is 50
// create binder that stops binding at first error
b := echo.QueryParamsBinder(c)
err := b.Int64("length", &length).
Int64s("ids", &opts.IDs).
Bool("active", &opts.Active).
BindError() // returns first binding error
if err != nil {
bErr := err.(*echo.BindingError)
return fmt.Errorf("my own custom error for field: %s values: %v", bErr.Field, bErr.Values)
}
fmt.Printf("active = %v, length = %v, ids = %v\n", opts.Active, length, opts.IDs)
return c.JSON(http.StatusOK, opts)
}
e := echo.New()
c := e.NewContext(
httptest.NewRequest(http.MethodGet, "/api/endpoint?active=true&length=25&ids=1&ids=2&ids=3", nil),
httptest.NewRecorder(),
)
_ = failFastRouteFunc(c)
// Output: active = true, length = 25, ids = [1 2 3]
}
func ExampleValueBinder_CustomFunc() {
// example route function that binds query params using custom function closure
routeFunc := func(c echo.Context) error {
length := int64(50) // default length is 50
var binary []byte
b := echo.QueryParamsBinder(c)
errs := b.Int64("length", &length).
CustomFunc("base64", func(values []string) []error {
if len(values) == 0 {
return nil
}
decoded, err := base64.URLEncoding.DecodeString(values[0])
if err != nil {
// in this example we use only first param value but url could contain multiple params in reality and
// therefore in theory produce multiple binding errors
return []error{echo.NewBindingError("base64", values[0:1], "failed to decode base64", err)}
}
binary = decoded
return nil
}).
BindErrors() // returns all errors
if errs != nil {
for _, err := range errs {
bErr := err.(*echo.BindingError)
log.Printf("in case you want to access what field: %s values: %v failed", bErr.Field, bErr.Values)
}
return fmt.Errorf("%v fields failed to bind", len(errs))
}
fmt.Printf("length = %v, base64 = %s", length, binary)
return c.JSON(http.StatusOK, "ok")
}
e := echo.New()
c := e.NewContext(
httptest.NewRequest(http.MethodGet, "/api/endpoint?length=25&base64=SGVsbG8gV29ybGQ%3D", nil),
httptest.NewRecorder(),
)
_ = routeFunc(c)
// Output: length = 25, base64 = Hello World
}
|