binding.go (3934B)
1 // Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2 // Use of this source code is governed by a MIT style 3 // license that can be found in the LICENSE file. 4 5 //go:build !nomsgpack 6 7 package binding 8 9 import "net/http" 10 11 // Content-Type MIME of the most common data formats. 12 const ( 13 MIMEJSON = "application/json" 14 MIMEHTML = "text/html" 15 MIMEXML = "application/xml" 16 MIMEXML2 = "text/xml" 17 MIMEPlain = "text/plain" 18 MIMEPOSTForm = "application/x-www-form-urlencoded" 19 MIMEMultipartPOSTForm = "multipart/form-data" 20 MIMEPROTOBUF = "application/x-protobuf" 21 MIMEMSGPACK = "application/x-msgpack" 22 MIMEMSGPACK2 = "application/msgpack" 23 MIMEYAML = "application/x-yaml" 24 MIMETOML = "application/toml" 25 ) 26 27 // Binding describes the interface which needs to be implemented for binding the 28 // data present in the request such as JSON request body, query parameters or 29 // the form POST. 30 type Binding interface { 31 Name() string 32 Bind(*http.Request, any) error 33 } 34 35 // BindingBody adds BindBody method to Binding. BindBody is similar with Bind, 36 // but it reads the body from supplied bytes instead of req.Body. 37 type BindingBody interface { 38 Binding 39 BindBody([]byte, any) error 40 } 41 42 // BindingUri adds BindUri method to Binding. BindUri is similar with Bind, 43 // but it reads the Params. 44 type BindingUri interface { 45 Name() string 46 BindUri(map[string][]string, any) error 47 } 48 49 // StructValidator is the minimal interface which needs to be implemented in 50 // order for it to be used as the validator engine for ensuring the correctness 51 // of the request. Gin provides a default implementation for this using 52 // https://github.com/go-playground/validator/tree/v10.6.1. 53 type StructValidator interface { 54 // ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right. 55 // If the received type is a slice|array, the validation should be performed travel on every element. 56 // If the received type is not a struct or slice|array, any validation should be skipped and nil must be returned. 57 // If the received type is a struct or pointer to a struct, the validation should be performed. 58 // If the struct is not valid or the validation itself fails, a descriptive error should be returned. 59 // Otherwise nil must be returned. 60 ValidateStruct(any) error 61 62 // Engine returns the underlying validator engine which powers the 63 // StructValidator implementation. 64 Engine() any 65 } 66 67 // Validator is the default validator which implements the StructValidator 68 // interface. It uses https://github.com/go-playground/validator/tree/v10.6.1 69 // under the hood. 70 var Validator StructValidator = &defaultValidator{} 71 72 // These implement the Binding interface and can be used to bind the data 73 // present in the request to struct instances. 74 var ( 75 JSON = jsonBinding{} 76 XML = xmlBinding{} 77 Form = formBinding{} 78 Query = queryBinding{} 79 FormPost = formPostBinding{} 80 FormMultipart = formMultipartBinding{} 81 ProtoBuf = protobufBinding{} 82 MsgPack = msgpackBinding{} 83 YAML = yamlBinding{} 84 Uri = uriBinding{} 85 Header = headerBinding{} 86 TOML = tomlBinding{} 87 ) 88 89 // Default returns the appropriate Binding instance based on the HTTP method 90 // and the content type. 91 func Default(method, contentType string) Binding { 92 if method == http.MethodGet { 93 return Form 94 } 95 96 switch contentType { 97 case MIMEJSON: 98 return JSON 99 case MIMEXML, MIMEXML2: 100 return XML 101 case MIMEPROTOBUF: 102 return ProtoBuf 103 case MIMEMSGPACK, MIMEMSGPACK2: 104 return MsgPack 105 case MIMEYAML: 106 return YAML 107 case MIMETOML: 108 return TOML 109 case MIMEMultipartPOSTForm: 110 return FormMultipart 111 default: // case MIMEPOSTForm: 112 return Form 113 } 114 } 115 116 func validate(obj any) error { 117 if Validator == nil { 118 return nil 119 } 120 return Validator.ValidateStruct(obj) 121 }