I don't think it's a good idea to couple an "ORM" with a web framework for Go. Go is, IMO, an inherently bad language to write an ORM in. I tried doing it once, as a convenience layer on top of Redis hash sets (kind of a crazy idea to begin with), and ran into an endless number of complications that led me to the conclusion that it was not the best solution to my problem.
I think its something you certainly can do. And if you have a great understanding of Go, and to a lesser extent C, you could probably do so with a reasonably good outcome. But I think what we've seen out of Go is that small micro services do not exemplify MVC and instead benefit from simpler abstractions that differ from traditional frameworks like Rails, Django, or Express.
That said, awesome work and I hope to have the time to try this out soon :) !
All of this is spot on. Go could benefit from a higher-level SQL layer, however.
As an example which has been annoying me the last few days, "database/sql" doesn't automatically prepare statements; so preparing is a separate step, and if you want to use a prepared statement in a transaction, it's yet another step to convert the prepared statement to one that will work with the transaction. I have convenience wrappers around this stuff to make my SQL calls less boilerplated and more readable.
It also doesn't offer high-level convenience functions for things like getting all rows mapped to structs in one go, and so on. And if you're going to support variable expansion in SQL queries, why not support named variables looked up through a map[string]interface{}?
What ActiveRecord gets right, and other ORMs (Hibernate, TopLink) don't, is that you don't want to abstract away SQL. You just want to map the data from/to your native (in this case) structs, because it's convenient.
>As an example which has been annoying me the last few days, "database/sql" doesn't automatically prepare statements; so preparing is a separate step
Not exactly. All the "database/sql" functions actually use prepared statements under the hood.
You only need to explicitly create a prepared statement if you're reusing it (since the internal ones are also auto-closed, although I think there's also some kind of connection cache so they might be reused anyway...)
> You only need to explicitly create a prepared statement if you're reusing it
It does prepare statements internally, but they're not reused, which is the main point of prepared statements: I know I'll run this thing a bazillion times, so I want to prepare it once and then just execute it with new parameters from now on.
As far as I can see, no caching is done [1]. There's a TODO note about maybe adding caching in the future.
This was a very kind and thoughtful way of putting this. I absolutely agree and really hate to see people rely on frameworks in Go (like Gorilla or Alice). These frameworks certainly have a place. But if you haven't written vanilla Go, you are really missing the point.
As jonesb6 mentions, Go really gives you a whole lot more than other languages like Python, Ruby, or Node. It has fantastic built-in routing (though I opt for httprouter) and a great template library (though I sometimes use Pongo2 to aid the port from Jinja2).
It appears to be very common for developers coming from Rails or Django or Express to try to find some other framework to force on Go. I'd just recommend that you give vanilla Go (possibly with some small libraries) a chance.
> and really hate to see people rely on frameworks in Go (like Gorilla or Alice). These frameworks certainly have a place. But if you haven't written vanilla Go, you are really missing the point.
Just to jump in: Gorilla (a collection of standalone packages) and Alice (a middleware chaining library) are definitely (far) far calls from frameworks - the submission, and other frameworks like Gin/Martini/etc. are more strongly coupled.
I wouldn't blame anyone who uses gorilla/mux and/or gorilla/schema to avoid writing their own a) pattern matching router (which net/http does not provide) and/or a comprehensive, battle-tested r.PostForm to struct mapper.
Otherwise I agree that Go the language—and Go the community—lean towards glueing smaller components together, rather than reaching for a kitchen sink solution.
I ultimately ended up modifying modelq (a tool that populates a Go text template with your DB schema as the context), and used that to generate CRUD code for my tables instead of dealing with reflection.
Turned out really nice.
Beego does something similar, but only for the initial setup, and then plugs the schema into their own orm, I was not that keen on. But using a template to roll my own has been great.
Email him, then set up a phone/video interview and then most likely either work remotely or sponsor him a work visa to where you are. So an H1-B for U.S.
I've often wanted to use Go for some silly little side projects and I typically just end up with a Flask orientated Python stack. This might give me some motivation to finally create something other than a todo list with Go.
I think its something you certainly can do. And if you have a great understanding of Go, and to a lesser extent C, you could probably do so with a reasonably good outcome. But I think what we've seen out of Go is that small micro services do not exemplify MVC and instead benefit from simpler abstractions that differ from traditional frameworks like Rails, Django, or Express.
That said, awesome work and I hope to have the time to try this out soon :) !