As an open-source project, mholt/binding has picked up 792 stars on GitHub (Go). Reflectionless data binding for Go's net/http (not actively maintained)
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
Moves data binding, validation, and error handling out of your application's handler
Reads Content-Type to deserialize form, multipart form, and JSON data from requests
No middleware: just a function call
Usable in any setting where net/http is present (Negroni, gocraft/web, std lib, etc.)
No reflection
Usage example
package main
import (
"fmt"
"net/http"
"github.com/mholt/binding"
)
// First define a type to hold the data
// (If the data comes from JSON, see: http://mholt.github.io/json-to-go)
type ContactForm struct {
User struct {
ID int
}
Email string
Message string
}
// Then provide a field mapping (pointer receiver is vital)
func (cf *ContactForm) FieldMap(req *http.Request) binding.FieldMap {
return binding.FieldMap{
&cf.User.ID: "user_id",
&cf.Email: "email",
&cf.Message: binding.Field{
Form: "message",
Required: true,
},
}
}
// Now your handlers can stay clean and simple
func handler(resp http.ResponseWriter, req *http.Request) {
contactForm := new(ContactForm)
if errs := binding.Bind(req, contactForm); errs != nil {
http.Error(resp, errs.Error(), http.StatusBadRequest)
return
}
fmt.Fprintf(resp, "From: %d\n", contactForm.User.ID)
fmt.Fprintf(resp, "Message: %s\n", contactForm.Message)
}
func main() {
http.HandleFunc("/contact", handler)
http.ListenAndServe(":3000", nil)
}
Multipart/form-data usage example
package main
import (
"bytes"
"fmt"
"github.com/mholt/binding"
"io"
"log"
"mime/multipart"
"net/http"
)
// We expect a multipart/form-data upload with
// a file field named 'data'
type MultipartForm struct {
Data *multipart.FileHeader `json:"data"`
}
func (f *MultipartForm) FieldMap(req *http.Request) binding.FieldMap {
return binding.FieldMap{
&f.Data: "data",
}
}
// Handlers are still clean and simple
func handler(resp http.ResponseWriter, req *http.Request) {
multipartForm := new(MultipartForm)
if errs := binding.Bind(req, multipartForm); errs != nil {
http.Error(resp, errs.Error(), http.StatusBadRequest)
return
}
// To access the file data you need to Open the file
// handler and read the bytes out.
var fh io.ReadCloser
var err error
if fh, err = multipartForm.Data.Open(); err != nil {
http.Error(resp,
fmt.Sprint("Error opening Mime::Data %v", err),
http.StatusInternalServerError)
return
}
defer fh.Close()
dataBytes := bytes.Buffer{}
var size int64
if size, err = dataBytes.ReadFrom(fh); err != nil {
http.Error(resp,
fmt.Sprint("Error reading Mime::Data %v", err),
http.StatusInternalServerError)
return
}
// Now you have the attachment in databytes.
// Maximum size is default is 10MB.
log.Printf("Read %v bytes with filename %s",
size, multipartForm.Data.Filename)
}
func main() {
http.HandleFunc("/upload", handler)
http.ListenAndServe(":3000", nil)
}
You can test from CLI using the excellent httpie client
http -f POST localhost:3000/upload data@myupload
Custom data validation
You may optionally have your type implement the binding.Validator interface to perform your own data validation. The .Validate() method is called after the struct is populated.
func (cf ContactForm) Validate(req *http.Request) error {
if cf.Message == "Go needs generics" {
return binding.Errors{
binding.NewError([]string{"message"}, "ComplaintError", "Go has generics. They're called interfaces.")
}
}
return nil
}
Binding custom types
For types you've defined, you can bind form data to it by implementing the Binder interface. Here's a contrived example:
If you can't add a method to the type, you can still specify a Binder func in the field spec. Here's a contrived example that binds an integer (not necessary, but you get the idea):
mholt/binding has 792 GitHub stars — refresh the page for the live number, or check github.com/mholt/binding. TopGit mirrors GitHub's count but does not claim minute-by-minute accuracy.
Is mholt/binding open source?
Yes — mholt/binding ships under the MIT license, which makes its source code freely readable (and, depending on license terms, forkable and reusable). Source: github.com/mholt/binding.
What is mholt/binding?
mholt/binding (mholt/binding) is a Go project on GitHub. From the project's own README: Reflectionless data binding for Go's net/http (not actively maintained)
Where can I see mholt/binding in action?
The project maintains a homepage at http://mholt.github.io/binding. The README tab on this page also usually contains screenshots and a quickstart.
Where do I read more about mholt/binding?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/mholt/binding is the definitive source.
Read full README in the tab above.
Curious whether binding is right for you?
Let ChatGPT, Claude, or Perplexity look into it — click below and see what AI actually says about binding.