Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: What is the current state of web frameworks in Golang?
56 points by freedomben on July 14, 2018 | hide | past | favorite | 38 comments
There are quite a few different web frameworks for Go, as well as just the built in `net/http`. Has any one package emerged as more common or standard than others?

What are you currently using? Do you like it?




The common reply in the Go community is "don't use a framework" or "roll your own".

The idea is that small packages suited to individual tasks are a better solution than a large framework package that includes more than you need, or tried to for your use case into a shared, common use case.

IMO, frameworks are great for rapid prototyping, but in Go and it's explicit programming style, most devs prefer to build most by have and only import a minimal number of packages for specific tasks.


Some common helpers are nice though, not sure that constitutes a framework but it definitely saves time not having to rewrite response compression and logging.


I don't do any Golang, but I do find myself agreeing with this sentiment in general.


Nobody has mentioned beego [1]. You can write a decent web-application using core Golang language. Yet, coding large applications require many features, like session handling, db connection, and so on. Instead of composing these from independent sources, you can use Beego which comes bundled with all of these.

If you are aware of Python ecosystem Beego is like Django (though Beego doesn't have an admin module).

I have been using Beego for couple of years now for my personal projects. I'm happy with it. It has almost all the features required for a web-application framework. It has good documentation too.

Just yesterday I released a side-project sheet2buffer[2], coded in Beego as backend and React as front-end.

If you are interested, I also wrote an introductory post about Beego[3].

[1]: https://beego.me/ [2]: https://sheet2buffer.com/ [3]: https://jjude.com/beego-intro/


I started a project about a year ago and I specifically wanted to answer this question. As a result, I wrote that project in revel.

Ultimately I don't hate revel and the result is an operational system today. I don't exactly regret the decision to use revel, but I also think that revel ultimately didn't bring many useful things to the party. I do know I'd have a better, more extensible easier to understand application if I had not used revel. I do know that if I was just using standard net/http I would have developed things faster. I found myself more often fighting against the framework to bend it to my will than benefitting from it.

All that said, I don't think I would have the confidence that "just use net/http" is the correct answer had I not done a project in revel.

I did a few projects before and after and in-between the revel project, while still actively developing and maintaining the revel project. Ultimately, I now find myself dreading working on the revel project to the point where, when I have time to spare, I'm much more likely to work on one of the non-revel projects.


I just started a project with Revel.

I dabbled with Go some years ago, and I was excited to try it again because I like statically typed languages and the simplicity of Go.

However, the package management story was insane. I had really hard time with that. Fortunately they are acknowledging the problems and fixing them.

Also, I kept missing Rust-style error handling. I've been programming in Rust extensively for a few years, and I thought Go might provide benefits of being "a simpler (garbage-collected) Rust". However, I keep longing some nice things from Rust.

Revel was... Ok. The fact that it builds the code while it's running is nice for rapid prototyping, but it was also really hard to fix if/when it didn't work. ( https://github.com/revel/revel/issues/1349 )

I found the default template engine to be a bit lackluster – template inheritance is the basic pattern I'd like to see everywhere as the default, but it didn't support that.

The project is still in an early phase so it's hard to say more than that.


After building apps in Martini and Revel, I’ve moved to using a smattering of decent (IMHO) packages good at 1 thing:

Let me render templates in a layout file with `yield` - https://github.com/unrolled/render

Let me quickly route with param support - https://github.com/julienschmidt/httprouter

Sessions, flash messages, and secure cookies - http://www.gorillatoolkit.org/pkg/sessions

POST parameter-to-structure binding (this is optional and easy enough to do by hand) - https://github.com/mholt/binding

I write my own middlewares for logging, auth, etc. Use viper for configuration, gorm for an ORM, and for anything more complicated, accept that you’re about to learn a whole lot about it because you’re gonna be writing it yourself.


OH! And json-to-go people, use json-to-go. Thank me (well, mholt really) later!


Here is a link for the lazy [1].

@mholt also created curl-to-go [2].

[1] https://mholt.github.io/json-to-go/

[2] https://mholt.github.io/curl-to-go/


To each their own, but I personally prefer the lego-building block-approach instead of the kitchen-sink approach of bigger frameworks. In Go at least, this scales quite nicely with your code IMO.

I use a couple of thin layers over net/http:

Gorilla mux: https://github.com/gorilla/mux

... Gets me easy route params and HTTP method filtering.

Negroni for middleware: https://github.com/urfave/negroni

... Super easy to roll your own, plus there's a bunch of random off-the-shelf middlewares that people have put together (see their README).

For talking with my DB, I just use sqlx (and sqlmock in my unit tests).

https://github.com/jmoiron/sqlx https://github.com/DATA-DOG/go-sqlmock


I generally just stick to net/http. In both small projects and large enterprise-y projects it's served well. I think most Go devs are roughly of similar opinion at this point.


gin[1] is a popular off-the-shelf solution that provides a lot of functionality for you. But as everdev said, it's pretty normal to gradually build up your own stack using the stdlib and possibly some smaller, more focused packages like httprouter[2] and the gorilla toolkit[3].

I actually have learned a lot about HTTP/HTTPS servers by working on a lower level and building up my stack! I recommend just starting with the stdlib and importing 3rd party code where you feel yourself limited by it. The first thing people probably adopt is a more expressive router.

[1] https://github.com/gin-gonic/gin

[2] https://github.com/julienschmidt/httprouter

[3] https://github.com/gorilla


While I'd agree that net/http is very capable, it still comes with a variety of gotchas when doing timeouts, logging, routing, etc. I think gin[1] is a good bet for jumping into building something without having to dive into doing a lot of http.Server research.

[1] https://github.com/gin-gonic/gin


Also love Gin - I've used this for maybe a dozen different projects. Sometimes I use the stdlib but when I do I usually end up trying to make an API like Gin. Gin just makes things so much faster to write good looking and well-performing code with their contexts and simple API.

My favorite thing about Gin: its README has 90% of what you need to know, with refined examples. I love when README's are so expressive, especially when Gitlab/Github/Bitbucket make the README the front page. Also, the README comes with the code when you clone so you can easily refer to it offline (I realize you could generate Godocs but I always forget the command to do this, and Godocs don't often have nice examples).

I'll also point out that Gin has an excellent collection of contributed middleware [1].

[1]: https://github.com/gin-gonic/contrib


I would like to mention aah framework [1], Documentation [2], Examples [3]; have a look and see. Does it match with your direction and project needs. I'm looking forward to your candid feedback.

Personally I would say it depends on your project needs, timeline, etc. Whether you're gonna use framework or roll your own.

My suggestion is to take your time to evaluate the frameworks and select the one which satisfy you the most. Generally none-of-the-framework would cover 100% of project needs; including aah.

Disclaimer: I'm the author aah framework.

[1]: https://aahframework.org [2]: https://docs.aahframework.org [3]: https://github.com/go-aah/examples


I've used Gorilla http://www.gorillatoolkit.org for 4+ years and I'm happy with it. It follows the signatures of net/http and routing is easier than regex.


I'm surprised there isn't more about Buffalo in this thread. It's creator (Mark Bates) has stated inspiration from the rails world, but has focused on building Buffalo to be very flexible.

It provides a nice boiler plate for the modern web app and pulls together a lot of the single packages mentioned here so you don't have to worry about wiring things together.

I've built a few small apps with it and thoroughly enjoyed the dev process.

(GoBuffalo.io)


I really like chi[0] - I think it strikes the right balance of being small and understandable, but also solving common problems (e.g. nested routes, URL parameters, etc.). It also uses standard Go conventions, so it's very interoperable and would be easy to migrate away from, if necessary.

[0]: https://github.com/go-chi/chi


chi is cool, but, isn't really a framework. Chi is just a router and that's a lot of why I think `chi` is quite good.

I happen to be a fan of web[0] even though its basically a dead project, it works fine and is minimal enough to not need any changes.

[0] https://github.com/gocraft/web


While chi is ‘just a router’ (and an exceptionally good one at that), it also includes a number of particularly useful middleware.


I don't mean to say "merely" a router. I think its good because it does one thing well.


I'll cautiously mention: https://github.com/valyala/fasthttp

It's a net/http replacement that is close to x10 in performance -- however it is not a drop in replacement and you should avoid it unless you really actually need the rps.

That's pretty much the opposite of a web framework.


I've been using echo[0] and sqlx[1]. I like it because it's performant and idiomatic.

It is minimalist compared to Rails or Django, but appropriately designed for the go world where you roll your own on top of tightly scoped libraries.

[0]: https://echo.labstack.com/

[1]: https://github.com/jmoiron/sqlx


Excuse my ignorance but does Go store libraries locally, in the way other package managers like NPM and Pip do?

I just looked at some Go source code and it references Github repos?

e.g.

> import "github.com/astaxie/beego"

Can I clone that repo into local and then import that? I wouldn't like to run a project at the mercy of someone elses remote repo.


You have to use a vendoring tool like Glide[1] for now, but Go is actively testing official vendoring support with vgo[2], where you use git tags for versions.

1. https://glide.sh/ 2. https://github.com/golang/go/wiki/PackageManagementTools


Check out GoKit - https://gokit.io

"Go kit is a programming toolkit for building microservices (or elegant monoliths) in Go. We solve common problems in distributed systems and application architecture so you can focus on delivering business value."


For database CRUD mappings to Web APIs, are the there any solutions ?


There is no real good framework and anybody can write a trie based router in 2 hours:

https://vluxe.io/golang-router.html

However, Go ecosystem is starting to look interesting library-wise, as long as your project doesn't involve enterprise integration with legacy XML services or SOAP, because Go sucks at mostly anything XML.

For templating I use Jet because the standard templating library is too basic for professional use https://github.com/CloudyKit/jet .

I don't use ORM, I use https://github.com/Masterminds/squirrel for query building and https://github.com/jmoiron/sqlx which helps deals with row<=>struct conversion. For database migrations, I use https://github.com/rubenv/sql-migrate , but if you need an ORM gorm https://github.com/jinzhu/gorm is OK if you do code first and sqlboiler https://github.com/volatiletech/sqlboiler is OK if you do database first.

For session handling I use scs github.com/alexedwards/scs , for converting form encoded data to go structs I use github.com/gorilla/schema, for logging I use zap https://github.com/uber-go/zap. For managing roles in an app I use either the voter pattern https://symfony.com/doc/current/security/voters.html in simple cases or casbin github.com/casbin/casbin . For background jobs I used https://github.com/gocraft/work and https://github.com/gocelery/gocelery , for caching i just use redis https://github.com/go-redis/redis , for data validation I used https://github.com/asaskevich/govalidator or https://github.com/go-ozzo/ozzo-validation . For sending mails to customers I used https://github.com/go-gomail/gomail

If i need html forms, I first describe form elements as a struct then write form helpers in jet templating to display them like that:

    type LoginForm struct {
            Login, Password string
            Form
    }

    func (form *LoginForm) validate(r *http.Request) error {
            r.ParseForm()
            form.Decoder().Decode(form, r.Form)
            form.Errors = map[string][]string{}
            if err := (requiredValidator{}).validate(form.Login); err != nil {
                    form.Errors["Login"] = append(form.Errors["Login"], err.Error())
            }
            if err := (requiredValidator{}).validate(form.Password); err != nil {
                    form.Errors["Password"] = append(form.Errors["Password"], err.Error())
            }
            return form.getErrors()
    }
    func (form LoginForm) LoginFormView() LoginFormView {
            return LoginFormView{Fields: []Field{
                    {Name: "Login", Label: "Email", Type: "text", Value: form.Login, Required: true, Errors: form.Errors["Login"]},
                    {Name: "Password", Label: "Password", Type: "password", Value: form.Password, Required: true, Errors: form.Errors["Password"]},
                    {Type: "submit", Value: "Submit", Required: true},
                    {Type: "reset", Value: "Reset", Required: true},
            }, Method: "POST", Name: "LoginForm"}
    }
Then I can just write an helper in jet to display the the form view:

    {* tag attributes *}
    {{ block attributes() }}
        {{range .}}
            {{.Key}}="{{.Value}}"
        {{end}}
    {{ end }}
    {* form field *}
    {{block field()}}
    <label>
        {{.Label}}
        <br/>
        {{if .Type == "textarea" }}
        {* textarea *}
        <textarea  name="{{.Name}}" {{ yield attributes() .Attributes }} >{{.Value}}</textarea>
        {{ else if .Type == "select" }}
        {* select *}
        <select name="{{.Name}}" {{yield attributes() .Attributes }}>
            {{ range .Options }}
            <option value="{{.Value}}" {{ if .Selected }} selected {{ end }}>{{.Label}}</option>
            {{ end }}
        </select>
        {{ else }}
        {* basic input *}
        <input type="{{.Type}}" name="{{.Name}}" {{ if isset(.Value) }} value="{{.Value}}" {{ end }}
        {{ yield attributes() .Attributes }} {{ if .Checked == true }} checked {{end}} />
        {{ end }}
    </label>
    {{end}}
    {* form template *}
    {{block form()}}
    <form action="{{.Action}}" name="{{.Name}}" method="{{.Method}}">
        <fieldset>
            {{ range .Fields }} {{yield field() .}} {{end}}
        </fieldset>
    </form>
    {{end}}
This is the exact app structure I use to deal with dependencies and filters :

https://medium.com/statuscode/how-i-write-go-http-services-a...


You have written your experience in detail.

If you don't mind. I would like to request you to have a look aah framework [1]? and share your candid feedback. I'm interested in your viewpoint. I'm the author of aah.

[1]: https://aahframework.org


Buffalo is an amazing kitchen-sink framework for go. Echo, is another great one though it is much more minimalistic


What about iris? All i see I propoganda in its docs. Is it what it actually claims?


DO NOT USE IRIS [1][2][3][4]

The author of this framework, who calls himself Kataras, is very unethical.

He fell into a big controversy with the management of his repositories, stealing several chunks of code from other popular projects without giving credits to their respective authors, and then using them to write benchmarks to make his own project look better than it is. He also spent several months creating bots to upvote his articles on different news aggregators and star his repositories to increase visibility in the GitHub Trending page. He also created several accounts in different websites (mostly Reddit) to act as a supporter of himself. The last time I heard about him, he had forked his own repositories multiple times to re-brand Iris with other names, hoping that people wouldn't notice, specially people who are just starting using Go.

[1] https://www.reddit.com/r/golang/comments/57tmp1/why_you_shou...

[2] http://www.florinpatan.ro/2016/10/why-you-should-not-use-iri...

[3] https://www.reddit.com/r/golang/comments/57w79c/why_you_real...

[4] https://github.com/avelino/awesome-go/pull/1137


Iris has been mired in drama since starting, which is good enough reason to avoid it.

One example, of many, https://github.com/avelino/awesome-go/pull/1137


I've been using Go for quite a long time (since before the 1.0 release); I've never heard of Iris before.

It looks interesting, but appears to be an "all in" approach. I gather that folks who like Django may like this a lot, but for me personally it rubs me the wrong way.

This may be due to my "anti-framework" mindset, but in my experience a lot of other Go developers have this same mindset. YMMV


does their package manager still suck?


net/http

I started with a more "batteries included" framework. There were too many impedance mismatches between the framework and other libraries. Having to whittle almost every 3rd-party library to fit within the framework was not worth the effort.

Switched to net/http and haven't looked back.


web frameworks aside what's really missing an ORM. i'll get excoriated for even suggesting that i shouldn't just use sqlx or whatever but using django/python makes me hate using go for web backends.


Me, an intellectual: "Yeah, so I prefer to write my own SQL so I know what is going on behind the scenes..."

And then 99% of that hardcore SQL is just:

    INSERT INTO users(name,email,password_hash,address1,address2,postalcode,city,country,created_at,updated_at) VALUES ($1,$2,$3,$4,$5,$6...)
Yeah, I'll try an ORM next time.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: