Hey, this is a lot of work.

What is, mapping fields? Bah. It's the same as using struct tags but with a greater degree of flexibility: being able to (optionally!) specify required fields, custom binding functions, and metadata all inline with your type, but out of the way of your application logic, is a huge win.

Why no reflection?

Reflection has its place, and arguably, data binding is a good use case for reflection. Pretty much every comparable library uses it. In fact, this package borrows ideas from the reflection-heavy martini-contrib/binding library. Reflection's downsides are well-known: slow, error-prone, and confusing.

The obscurity of what is really happening and the delicacy of using reflect motivated a new approach. And that's all this package is: a different approach to data binding. Let idiomatic Go shine in all its glory, and see what really can be done without having to use the reflect package.

But type assertions are reflection...

That's debatable. The Go language by itself does not facilitate run-time reflection. Type switches/assertions are inherently way safer and easier to use than the reflect package, which "implements run-time reflection." So anyway, there's no real reflection going on in this package. (Not because reflection is bad, but simply because there is another way.)

...and encoding/json uses reflection!

Ah, yup. Beyond this binding package itself, there are no guarantees what the individual deserializers (other packages) are going to do.

[anything else about reflection]

Reflection is not the point here. Yes, it's "reflectionless data binding for Go" -- but that's just a description. Instead, don't worry about whether reflection is good or bad for this. Just enjoy clear, idiomatic Go code.

What are the goals of this package?

"Keep it lightweight, idiomatic, flexible, and simple, stupid."

What about performance?

What about it? I mean, you can run benchmarks if you want. As with anything else, if you need the absolutest best performance ever invented, don't use a general-purpose library like this. Instead, code up some highly optimized routine yourself for your specific use case. For regular use, we're talking about a difference of microseconds... not a big deal in most cases.

How did this project start?

Initially, it was supposed to be a contributed middleware for Negroni. However, it quickly became clear that there was no reason to make this package middleware: all you need is a function call. So it became a generalized binding package that can be used anywhere, with nearly any framework or none at all, for nearly any request format.

Why isn't this project called "vampire"?

Because there's no black magic here.