The project I'm working on is using a custom Binder to support two datatypes not natively supported by echo's Binder. When upgrading from echo 2 to echo 3, this has caused some problems.
I'm wondering if any thought has gone into supporting a more general way to extend the Binder's data type translation. I'm thinking of modifying it to support similar, if not identical to, sql's Scanner interface.
For our use case, this would completely eliminate the need for a custom Binder (which is a 98% copy of echo 2's binder).
I think it should be a non-breaking change, and completely backward-compatible, too. As long as checking for the Scanner interface is done after the existing built-in datatypes, the only room for breaking backward compatibility that I can imagine is that some structs which would have failed previously, will now succeed.
Thoughts?
When upgrading from echo 2 to echo 3, this has caused some problems.
What kind of problem? In v3 Binder is made public.
Aren't Scanner and Binder interface similar? May be I am missing something.
What kind of problem? In v3 Binder is make public.
The problem isn't that the Binder isn't public, the problem is that it doesn't support arbitrary data types.
In upgrading from echo 2 to echo 3, we've found that some forms are no longer bound properly. I can't say exactly what changed that caused the problem--there have been enough subtle changes between echo 2 and 3 that finding the exact cause is a bit daunting, and I'm not sure if it's entirely worth it.
Aren't Scanner and Binder interface similar? May be I am missing something.
No. I don't believe they're very similar at all. The Binder interface, as I understand it, lets you plug in an entirely new binder (which is good, for what it's worth). The Scanner interface lets you declare a datatype that can "bind" itself. For example, to add support for RFC822-formatted date strings, all I need is:
type Timestamp time.Time
func (t *Timestamp) Scan(src interface{}) error {
t, err := time.Parse(time.RFC822Z, src.(string))
return err
}
With this, one can bind to a struct such as the following, without having to create a new binder at all:
type Foo struct {
Name string `form:"name"`
Created Timestamp `form:"created"`
}
If I'm missing some subtle functionality of the Binder interface, please enlighten me.
If you'd like to see a PR to better understand my proposed changes, I can put that together, too.
@flimzy You can send a PR to have a better understanding, doesn't have to a final one - just enough to understand and we can work through it later.
PR #764 is not fully functional yet, but should be sufficient to show what I have in mind.
Any further thoughts on this, @vishr, after reviewing the PR?
@flimzy It is still under review. I will get back to it soon.
Most helpful comment
@flimzy You can send a PR to have a better understanding, doesn't have to a final one - just enough to understand and we can work through it later.