github.com/bytedance/go-tagexpr@v2.7.5-0.20210114074101-de5b8743ad85+incompatible/binding/README.md (about)

     1  # binding [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/bytedance/go-tagexpr/binding)
     2  
     3  A powerful HTTP request parameters binder that supports struct tag expression.
     4  
     5  ## Example
     6  
     7  ```go
     8  func Example() {
     9  	type InfoRequest struct {
    10  		Name          string   `path:"name"`
    11  		Year          []int    `query:"year"`
    12  		Email         *string  `json:"email" vd:"email($)"`
    13  		Friendly      bool     `json:"friendly"`
    14  		Status        string   `json:"status" default:"single"`
    15  		Pie           float32  `json:"pie,required"`
    16  		Hobby         []string `json:",required"`
    17  		BodyNotFound  *int     `json:"BodyNotFound"`
    18  		Authorization string   `header:"Authorization,required" vd:"$=='Basic 123456'"`
    19  		SessionID     string   `cookie:"sessionid,required"`
    20  		AutoBody      string
    21  		AutoNotFound  *string
    22  		TimeRFC3339   time.Time `query:"t"`
    23  	}
    24  
    25  	args := new(InfoRequest)
    26  	binder := binding.New(nil)
    27  	err := binder.BindAndValidate(args, requestExample(), new(testPathParams))
    28  
    29  	fmt.Println("bind and validate result:")
    30  
    31  	fmt.Printf("error: %v\n", err)
    32  
    33  	b, _ := json.MarshalIndent(args, "", "	")
    34  	fmt.Printf("args JSON string:\n%s\n", b)
    35  
    36  	// Output:
    37  	// request:
    38  	// POST /info/henrylee2cn?year=2018&year=2019&t=2019-09-04T18%3A04%3A08%2B08%3A00 HTTP/1.1
    39  	// Host: localhost
    40  	// User-Agent: Go-http-client/1.1
    41  	// Transfer-Encoding: chunked
    42  	// Authorization: Basic 123456
    43  	// Content-Type: application/json;charset=utf-8
    44  	// Cookie: sessionid=987654
    45  	//
    46  	// 83
    47  	// {"AutoBody":"autobody_test","Hobby":["Coding","Mountain climbing"],"email":"henrylee2cn@gmail.com","friendly":true,"pie":3.1415926}
    48  	// 0
    49  	//
    50  	// bind and validate result:
    51  	// error: <nil>
    52  	// args JSON string:
    53  	// {
    54  	// 	"Name": "henrylee2cn",
    55  	// 	"Year": [
    56  	// 		2018,
    57  	// 		2019
    58  	// 	],
    59  	// 	"email": "henrylee2cn@gmail.com",
    60  	// 	"friendly": true,
    61  	// 	"status": "single",
    62  	// 	"pie": 3.1415925,
    63  	// 	"Hobby": [
    64  	// 		"Coding",
    65  	// 		"Mountain climbing"
    66  	// 	],
    67  	// 	"BodyNotFound": null,
    68  	// 	"Authorization": "Basic 123456",
    69  	// 	"SessionID": "987654",
    70  	// 	"AutoBody": "autobody_test",
    71  	// 	"AutoNotFound": null,
    72  	// 	"TimeRFC3339": "2019-09-04T18:04:08+08:00"
    73  	// }
    74  }
    75  ...
    76  ```
    77  
    78  ## Syntax
    79  
    80  The parameter position in HTTP request:
    81  
    82  |expression|renameable|description|
    83  |----------|----------|-----------|
    84  |`path:"$name"` or `path:"$name,required"`|Yes|URL path parameter|
    85  |`query:"$name"` or `query:"$name,required"`|Yes|URL query parameter|
    86  |`raw_body:""` or `raw_body:"required"`|Yes|The raw bytes of body|
    87  |`form:"$name"` or `form:"$name,required"`|Yes|The field in body, support:<br>`application/x-www-form-urlencoded`,<br>`multipart/form-data`|
    88  |`protobuf:"...(raw syntax)"`|No|The field in body, support:<br>`application/x-protobuf`|
    89  |`json:"$name"` or `json:"$name,required"`|No|The field in body, support:<br>`application/json`|
    90  |`header:"$name"` or `header:"$name,required"`|Yes|Header parameter|
    91  |`cookie:"$name"` or `cookie:"$name,required"`|Yes|Cookie parameter|
    92  |`default:"$value"`|Yes|Default parameter|
    93  |`vd:"...(tagexpr validator syntax)"`|Yes|The tagexpr expression of validator|
    94  
    95  **NOTE:**
    96  
    97  - `"$name"` is variable placeholder
    98  - If `"$name"` is empty, use the name of field
    99  - If `"$name"` is `-`, omit the field
   100  - Expression `required` or `req` indicates that the parameter is required
   101  - `default:"$value"` defines the default value for fallback when no binding is successful
   102  - If no position is tagged, try bind parameters from the body when the request has body,
   103    <br>otherwise try bind from the URL query
   104  - When there is unexportable and no tags, omit the field
   105  - When there are multiple tags, or exportable and no tags, the order in which to try to bind is:
   106    1. path
   107    2. form
   108    3. query
   109    4. cookie
   110    5. header
   111    6. protobuf
   112    7. json
   113    8. default
   114  
   115  ## Type Unmarshalor
   116  
   117  TimeRFC3339-binding function is registered by default.
   118  
   119  Register your own binding function for the specified type, e.g.:
   120  
   121  ```go
   122  MustRegTypeUnmarshal(reflect.TypeOf(time.Time{}), func(v string, emptyAsZero bool) (reflect.Value, error) {
   123  	if v == "" && emptyAsZero {
   124  		return reflect.ValueOf(time.Time{}), nil
   125  	}
   126  	t, err := time.Parse(time.RFC3339, v)
   127  	if err != nil {
   128  		return reflect.Value{}, err
   129  	}
   130  	return reflect.ValueOf(t), nil
   131  })
   132  ```