codegangsta/martini-contrib — pull request #34 by mholt (2013-12-02 17:53:35+00:00)
Title: New "binding" package replaces "Form" middleware

Package "binding" combines the Form middleware with new Json, Bind, and Validate middleware.

### Bind

`Bind` is the highest-level middleware. It takes a request with a Form or JSON payload and converts it to a new struct you pass in. If a Content-Type is specified, it immediately deserializes the request into that struct according to that content type. Otherwise, it guesses until it finds one that works. (Right now, it only supports Form and JSON; XML could be added later if desired.) Bind also performs validation on the request so the application only sees the request, with the populated struct, if deserialization and validation succeeded. It works like [shown here](https://github.com/codegangsta/martini-contrib/issues/5#issuecomment-29423870).

### Form

`Form` middleware works like it did before, deserializing form-urlencoded payload or query string into a struct, except it does not validate that the "required" attribute is satisfied. It only populates a struct and performs no validation. (Validation is now performed with the Validate middleware.)

### JSON

`Json` middleware works like `Form` except it deserializes a JSON payload in the request body into the struct. It performs no validation.

### Validate

`Validate` middleware only performs validation. The struct passed in is presumed to be populated from the request already. It first checks each field for the "required" attribute, and if it is required, ensures that it is a non-zero value for that field's type. (That means if you want to accept 0 in `int` fields, or false in `bool` fields, etc, don't mark it as required.)

After the required property is validated, it checks to see if the struct implements the Validator interface:

Validator interface {
Validate(*Errors, *http.Request)
}

If so, the `Validate()` method is called on that struct. [This comment on issue 5](https://github.com/codegangsta/martini-contrib/issues/5#issuecomment-29423870) also describes how that works.

This PR should effectively fix #5. It's a massive change so feel free to make tweaks, and feedback is welcome. I strongly suspect we'll be using this internally at work so it's in our best interest to make this good, too.