From 52c311bda1f6a2948901f0e2079529ae0c1de4fc Mon Sep 17 00:00:00 2001 From: 1911860538 Date: Thu, 23 Oct 2025 20:19:02 +0800 Subject: [PATCH] refactor(binding): separate the common logic and msgpack-specific implementation --- binding/binding.go | 32 ------------- binding/binding_msgpack.go | 46 +++++++++++++++++++ binding/binding_nomsgpack.go | 89 ++---------------------------------- 3 files changed, 49 insertions(+), 118 deletions(-) create mode 100644 binding/binding_msgpack.go diff --git a/binding/binding.go b/binding/binding.go index 702d0e82..5a63f809 100644 --- a/binding/binding.go +++ b/binding/binding.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a MIT style // license that can be found in the LICENSE file. -//go:build !nomsgpack - package binding import "net/http" @@ -18,8 +16,6 @@ const ( MIMEPOSTForm = "application/x-www-form-urlencoded" MIMEMultipartPOSTForm = "multipart/form-data" MIMEPROTOBUF = "application/x-protobuf" - MIMEMSGPACK = "application/x-msgpack" - MIMEMSGPACK2 = "application/msgpack" MIMEYAML = "application/x-yaml" MIMEYAML2 = "application/yaml" MIMETOML = "application/toml" @@ -80,7 +76,6 @@ var ( FormPost Binding = formPostBinding{} FormMultipart Binding = formMultipartBinding{} ProtoBuf BindingBody = protobufBinding{} - MsgPack BindingBody = msgpackBinding{} YAML BindingBody = yamlBinding{} Uri BindingUri = uriBinding{} Header Binding = headerBinding{} @@ -88,33 +83,6 @@ var ( TOML BindingBody = tomlBinding{} ) -// Default returns the appropriate Binding instance based on the HTTP method -// and the content type. -func Default(method, contentType string) Binding { - if method == http.MethodGet { - return Form - } - - switch contentType { - case MIMEJSON: - return JSON - case MIMEXML, MIMEXML2: - return XML - case MIMEPROTOBUF: - return ProtoBuf - case MIMEMSGPACK, MIMEMSGPACK2: - return MsgPack - case MIMEYAML, MIMEYAML2: - return YAML - case MIMETOML: - return TOML - case MIMEMultipartPOSTForm: - return FormMultipart - default: // case MIMEPOSTForm: - return Form - } -} - func validate(obj any) error { if Validator == nil { return nil diff --git a/binding/binding_msgpack.go b/binding/binding_msgpack.go new file mode 100644 index 00000000..f1544655 --- /dev/null +++ b/binding/binding_msgpack.go @@ -0,0 +1,46 @@ +// Copyright 2025 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +//go:build !nomsgpack + +package binding + +import "net/http" + +// Content-Type MIME of msgpack. +const ( + MIMEMSGPACK = "application/x-msgpack" + MIMEMSGPACK2 = "application/msgpack" +) + +// MsgPack implement the BindingBody interface. +var MsgPack BindingBody = msgpackBinding{} + +// Default returns the appropriate Binding instance based on the HTTP method +// and the content type. +func Default(method, contentType string) Binding { + if method == http.MethodGet { + return Form + } + + switch contentType { + case MIMEMSGPACK, MIMEMSGPACK2: + return MsgPack + + case MIMEJSON: + return JSON + case MIMEXML, MIMEXML2: + return XML + case MIMEPROTOBUF: + return ProtoBuf + case MIMEYAML, MIMEYAML2: + return YAML + case MIMETOML: + return TOML + case MIMEMultipartPOSTForm: + return FormMultipart + default: // case MIMEPOSTForm: + return Form + } +} diff --git a/binding/binding_nomsgpack.go b/binding/binding_nomsgpack.go index c8e61310..e98cc18f 100644 --- a/binding/binding_nomsgpack.go +++ b/binding/binding_nomsgpack.go @@ -8,86 +8,10 @@ package binding import "net/http" -// Content-Type MIME of the most common data formats. -const ( - MIMEJSON = "application/json" - MIMEHTML = "text/html" - MIMEXML = "application/xml" - MIMEXML2 = "text/xml" - MIMEPlain = "text/plain" - MIMEPOSTForm = "application/x-www-form-urlencoded" - MIMEMultipartPOSTForm = "multipart/form-data" - MIMEPROTOBUF = "application/x-protobuf" - MIMEYAML = "application/x-yaml" - MIMEYAML2 = "application/yaml" - MIMETOML = "application/toml" -) - -// Binding describes the interface which needs to be implemented for binding the -// data present in the request such as JSON request body, query parameters or -// the form POST. -type Binding interface { - Name() string - Bind(*http.Request, any) error -} - -// BindingBody adds BindBody method to Binding. BindBody is similar with Bind, -// but it reads the body from supplied bytes instead of req.Body. -type BindingBody interface { - Binding - BindBody([]byte, any) error -} - -// BindingUri adds BindUri method to Binding. BindUri is similar with Bind, -// but it reads the Params. -type BindingUri interface { - Name() string - BindUri(map[string][]string, any) error -} - -// StructValidator is the minimal interface which needs to be implemented in -// order for it to be used as the validator engine for ensuring the correctness -// of the request. Gin provides a default implementation for this using -// https://github.com/go-playground/validator/tree/v10.6.1. -type StructValidator interface { - // ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right. - // If the received type is not a struct, any validation should be skipped and nil must be returned. - // If the received type is a struct or pointer to a struct, the validation should be performed. - // If the struct is not valid or the validation itself fails, a descriptive error should be returned. - // Otherwise nil must be returned. - ValidateStruct(any) error - - // Engine returns the underlying validator engine which powers the - // StructValidator implementation. - Engine() any -} - -// Validator is the default validator which implements the StructValidator -// interface. It uses https://github.com/go-playground/validator/tree/v10.6.1 -// under the hood. -var Validator StructValidator = &defaultValidator{} - -// These implement the Binding interface and can be used to bind the data -// present in the request to struct instances. -var ( - JSON = jsonBinding{} - XML = xmlBinding{} - Form = formBinding{} - Query = queryBinding{} - FormPost = formPostBinding{} - FormMultipart = formMultipartBinding{} - ProtoBuf = protobufBinding{} - YAML = yamlBinding{} - Uri = uriBinding{} - Header = headerBinding{} - TOML = tomlBinding{} - Plain = plainBinding{} -) - // Default returns the appropriate Binding instance based on the HTTP method // and the content type. func Default(method, contentType string) Binding { - if method == "GET" { + if method == http.MethodGet { return Form } @@ -100,18 +24,11 @@ func Default(method, contentType string) Binding { return ProtoBuf case MIMEYAML, MIMEYAML2: return YAML - case MIMEMultipartPOSTForm: - return FormMultipart case MIMETOML: return TOML + case MIMEMultipartPOSTForm: + return FormMultipart default: // case MIMEPOSTForm: return Form } } - -func validate(obj any) error { - if Validator == nil { - return nil - } - return Validator.ValidateStruct(obj) -}