Documentation
¶
Overview ¶
A MVC binder for free-style of function handler with *gin.Context
Abstract ¶
There are may tedious processes for coding on web service:
- Type conversion from HTTP query parameter to desired type in GoLang.
- Binding body of HTTP POST to JSON object in GoLang. 2.1. Perform post-process(e.x. trim text) of binding data 2.2. Perform data validation of binding data
- Convert the result data to JSON response.
Gin has provided foundation features on simple and versatile web application, this framework try to enhance the building of web application on instinct way.
MvcHandler ¶
A MVC handler can be any function with ruled types of parameter and defined returned types.
type MvcHandler interface{}
You can define handler of supported:
func(req *http.Request, params *gin.Params) OutputHandler { return TextOutputHandler("Hello World") } func( data *struct { // Binding data from form(or query string) Name string `form:"name" default:"anonymous"` // Binding data from uri Age int `uri:"id" default:"0"` // Binding data from header SessionId string `header:"session_id"` // Binding data from JSON Weight int `json:"weight"` }, ) OutputHandler { return TextOutputHandler("Hello World") }
WrapToGinHandler ¶
After you define the MVC handler, you could use "MvcBuilder.WrapToGinHandler()" to convert your handler to "gin.HandlerFunc".
mvcBuilder := NewMvcConfig().ToBuilder() engine.Get("/your-web-service", mvcBuilder.WrapToGinHandler(your_mvc_handler))
Parameters of Handler ¶
"<struct>" - See parameter tags for automatic binding
This type of value woule be checked by ogin.ConformAndValidateStruct automatically.
"*gin.Context" - The context object of current request
TODO-Parameters of Handler ¶
"json.Unmarshaler" - If the type of value is json.Unmarshaler, use the UnmarshalJSON([]byte) function of the value
This type of value woule be checked by ogin.ConformAndValidateStruct automatically.
"gin.ResponseWriter" - See "gin.ResponseWriter"
"gin.Params" - See "gin.Params"
"*http.Request" - See "http.Request"
"http.ResponseWriter" - See "http.ResponseWriter"
"*url.URL" - See "url.URL"
"*multipart.Reader" - See "multipart.Reader"; Once you use *multipart.Form, the reader would reach EOF.
"*multipart.Form" - See "multipart.Form"
"*validator.Validate" - See go-playground/validator.v10
Tagging Struct ¶
There are various definition of tags could be used on struct:
type MyData struct { // Binding data from form(or query string) Name string `form:"name"` // Binding data from uri Age int `uri:"id"` // Binding data from header SessionId string `header:"session_id"` // Binding data from JSON Weight int `json:"weight"` }
Form(Query string), header, or JSON body
form:"field_1" - Use query parameter param_name_1 as binding value form:"field_2" - Must be bool type, used to indicate whether or not has viable value for this parameter header:"header_value_1" - Use the value of URI parameter pm_1 as binding value header:"header_value_2" - Use the form value of in_1 as binding value uri:"uri_v_1" - Must be bool type, used to indicate whether or not has viable value for this parameter uri:"uri_v_2" - Use the header value of Content-Type as binding value json:"v1" - Must be bool type, used to indicate whether or not has viable value for this parameter json:"v2" - Must be bool type, used to indicate whether or not has viable value for this parameter
TODO-Default Value
default:"20" - Gives value 20 if the value of binding is empty default:"[20,40,30]" - Gives value [20, 40, 30](as array, no space)if the value of binding is empty
By default, if the value of binding is existing, the framework would use the default value of binding type.
Data Validation ¶
The Gin framework uses "go-playground/validator"(v10) as default validator.
See Also: Documentations of Gin's Binding: https://github.com/gin-gonic/gin#model-binding-and-validation
You can register "ErrorHandler" to resolve errors comes from "MvcHandler"
See
"MvcConfig.RegisterErrorHandlers(ErrorHandler)"
OutputHandler ¶
You can provides various combination of returned value for "MvcHandler":
OutputHandler - Single value of output body (OutputHandler, error) - OutputHandler nad error (OutputHandler, int) - response status and OutputHandler (OutputHandler, int, error) - response status, OutputHandler, and error
Implements "OutputHandler"
You can implements "OutputHandler" of returned type:
type MyCar struct {} func (self *MyUser) Output(context *gin.Context) error { context.JSON(200, "[1, 11, 21]") return nil } func yourHandler() *MyCar { return nil }
see: "JsonOutputHandler", "TextOutputHandler", "XmlOutputHandler", etc.
TODO-Return value by other types ¶
"json.Marshaler" - If the type of returned value is json.Marshaler, use JsonOutputHandler() as output type
"string" - If the type of returned value is string, use TextOutputHandler() as output type
"fmt.Stringer" - As same as string
Index ¶
- Constants
- type ErrorHandler
- type MvcBuilder
- type MvcConfig
- func (self *MvcConfig) RegisterErrorHandlers(errHandlers ...ErrorHandler) *MvcConfig
- func (self *MvcConfig) RegisterParamAsFieldResolvers(paramAsFieldResolvers ...ParamAsFieldResolver) *MvcConfig
- func (self *MvcConfig) RegisterParamResolvers(paramResolvers ...ParamResolver) *MvcConfig
- func (self *MvcConfig) ToBuilder() MvcBuilder
- type MvcHandler
- type OutputHandler
- func AutoDetectOutputHandler(code int, v interface{}) OutputHandler
- func HtmlOutputHandler(code int, name string, v interface{}) OutputHandler
- func JsonOutputHandler(code int, v interface{}) OutputHandler
- func ProtoBufOutputHandler(code int, v interface{}) OutputHandler
- func TextOutputHandler(code int, v interface{}) OutputHandler
- func XmlOutputHandler(code int, v interface{}) OutputHandler
- func YamlOutputHandler(code int, v interface{}) OutputHandler
- type OutputHandlerFunc
- type ParamAsFieldResolver
- type ParamResolver
- type Resolvable
- type ResolvableField
- type StoppableServer
Examples ¶
Constants ¶
const (
DEFAULT_TIMEOUT = 5
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ErrorHandler ¶
type ErrorHandler interface { // Checks whether or not the error bould be resolved CanHandle(*gin.Context, error) bool // Handles the error HandleError(*gin.Context, error) error }
Process and resolves the generated error by MvcHandler
type MvcBuilder ¶
type MvcBuilder interface { // The wrapper method WrapToGinHandler(MvcHandler) func(c *gin.Context) }
This build warp MVC handler to gin handler(as "func(c *gin.Context)")
Example (WrapToGinHandler) ¶
package main import ( "fmt" "net/http" "net/http/httptest" "strings" ) func main() { /** * Prepares request */ req := httptest.NewRequest( "POST", "/sample-uri", strings.NewReader(`{ "id": 281, "color": 3 , "code": "IU-762"}`), ) req.Header.Set("Content-Type", "application/json") sampleContext, resp := newContext() sampleContext.Request = req // :~) /** * Wraps the customized handler */ handler := NewMvcConfig().ToBuilder(). WrapToGinHandler(sampleHandler) handler(sampleContext) // :~) fmt.Printf("Resp[%d]: %s", resp.Code, resp.Body.String()) } type leopard struct { Id int `json:"id"` Color uint8 `json:"color"` Code string `json:"code"` } func sampleHandler(leopard *leopard) OutputHandler { sampleOutput := []interface{}{ 10, 20, leopard.Code, } return JsonOutputHandler(http.StatusOK, sampleOutput) }
Output: Resp[200]: [10,20,"IU-762"]
type MvcConfig ¶
type MvcConfig struct {
// contains filtered or unexported fields
}
The configuration used by "MvcBuilder"
func NewMvcConfig ¶
func NewMvcConfig() *MvcConfig
Constructs MVC configuration with default values
EnableValidator(bool) - true
Example (ToBuilder) ¶
builder := NewMvcConfig().ToBuilder() _ = builder
Output:
func (*MvcConfig) RegisterErrorHandlers ¶
func (self *MvcConfig) RegisterErrorHandlers(errHandlers ...ErrorHandler) *MvcConfig
Registers multiple handlers for error
By default, any unhandled error would be output as JSON and 500(Internal server error) status
func (*MvcConfig) RegisterParamAsFieldResolvers ¶
func (self *MvcConfig) RegisterParamAsFieldResolvers(paramAsFieldResolvers ...ParamAsFieldResolver) *MvcConfig
Registers multiple resolvers of field
func (*MvcConfig) RegisterParamResolvers ¶
func (self *MvcConfig) RegisterParamResolvers(paramResolvers ...ParamResolver) *MvcConfig
Registers multiple resolvers
func (*MvcConfig) ToBuilder ¶
func (self *MvcConfig) ToBuilder() MvcBuilder
Gets the instance of "MvcBuilder"
type OutputHandler ¶
Main interface for generating response
Example ¶
package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) type text3OutputHandler struct{} func (*text3OutputHandler) Output(context *gin.Context) error { context.Data(http.StatusUseProxy, "plain/text", []byte("hello world")) return nil } func text3Handler() OutputHandler { return &text3OutputHandler{} } func main() { /** * Prepares request */ sampleContext, resp := newContext() // :~) /** * Wraps the customized handler */ handler := NewMvcConfig().ToBuilder(). WrapToGinHandler(text3Handler) handler(sampleContext) // :~) fmt.Printf("Resp[%d]: %s", resp.Code, resp.Body.String()) }
Output: Resp[305]: hello world
func AutoDetectOutputHandler ¶
func AutoDetectOutputHandler(code int, v interface{}) OutputHandler
With HTTP header of "Accepted", this function builds "OutputHandler" by the supported MIME type:
application/json, application/xml, text/xml, text/plain, application/x-protobuf, application/x-yaml
func HtmlOutputHandler ¶
func HtmlOutputHandler(code int, name string, v interface{}) OutputHandler
Uses "(*gin.Context).HTML(code, name, v)" to perform response
func JsonOutputHandler ¶
func JsonOutputHandler(code int, v interface{}) OutputHandler
Uses "(*gin.Context).JSON(http.StatusOK, v)" to perform response
func ProtoBufOutputHandler ¶
func ProtoBufOutputHandler(code int, v interface{}) OutputHandler
Uses "(*gin.Context).ProtoBuf(code, v)" to perform response
func TextOutputHandler ¶
func TextOutputHandler(code int, v interface{}) OutputHandler
Uses "(*gin.Context).String(code, v)" to perform response
func XmlOutputHandler ¶
func XmlOutputHandler(code int, v interface{}) OutputHandler
Uses "(*gin.Context).XML(code, v)" to perform response
func YamlOutputHandler ¶
func YamlOutputHandler(code int, v interface{}) OutputHandler
Uses "(*gin.Context).YAML(code, v)" to perform response
type OutputHandlerFunc ¶
Functional type of "OutputHandler"
Example ¶
package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) func text3OutputFunc(context *gin.Context) error { context.Data(http.StatusNotAcceptable, "plain/text", []byte("This is fine")) return nil } func text3HandlerByFunc() OutputHandler { return OutputHandlerFunc(text3OutputFunc) } func main() { /** * Prepares request */ sampleContext, resp := newContext() // :~) /** * Wraps the customized handler */ handler := NewMvcConfig().ToBuilder(). WrapToGinHandler(text3OutputFunc) handler(sampleContext) // :~) fmt.Printf("Resp[%d]: %s", resp.Code, resp.Body.String()) }
Output: Resp[406]: This is fine
type ParamAsFieldResolver ¶
type ParamAsFieldResolver interface { // Checks whether or not the value of field could be resolved CanResolve(*reflect.StructField) bool // Constructs and initializes the value of the struct's field Resolve(*gin.Context, *reflect.StructField) (interface{}, error) }
Constructs and resolves parameter(for field of struct) fed to "MvcHandler"
type ParamResolver ¶
type ParamResolver interface { // Checks whether or not the type of value could be resolved CanResolve(reflect.Type) bool // Constructs and initializes the value of parameter Resolve(*gin.Context, reflect.Type) (interface{}, error) }
Constructs and resolves parameter fed to "MvcHandler"
type Resolvable ¶
A type could implements this interface to customize resolving
type ResolvableField ¶
type ResolvableField interface {
ResolveField(*gin.Context, *reflect.StructField) error
}
A type could implements this interface to customize resolving when it is enclosed as field of a struct
type StoppableServer ¶
type StoppableServer struct {
// contains filtered or unexported fields
}
Provides methods to shutdown server gracefully.
func NewStoppableServer ¶
func NewStoppableServer(newEngine *gin.Engine) *StoppableServer
Constructs a new instance of "*StoppableServer" with "*gin.Engine"
func (*StoppableServer) ListenAndServeAsync ¶
func (self *StoppableServer) ListenAndServeAsync(addr string)
Starts server
func (*StoppableServer) Shutdown ¶
func (self *StoppableServer) Shutdown()
Shutdowns server with 5 seconds timeout by default.
func (*StoppableServer) ShutdownWithTimeout ¶
func (self *StoppableServer) ShutdownWithTimeout(duration time.Duration)
Shutdowns server with timeout.