Ask HN: What is the current state of web frameworks in Golang?
There is no real good framework and anybody can write a trie based router in 2 hours:<p><a href="https:&#x2F;&#x2F;vluxe.io&#x2F;golang-router.html" rel="nofollow">https:&#x2F;&#x2F;vluxe.io&#x2F;golang-router.html</a><p>However, Go ecosystem is starting to look interesting library-wise, as long as your project doesn&#x27;t involve enterprise integration with legacy XML services or SOAP, because Go sucks at mostly anything XML.<p>For templating I use Jet because the standard templating library is too basic for professional use <a href="https:&#x2F;&#x2F;github.com&#x2F;CloudyKit&#x2F;jet" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;CloudyKit&#x2F;jet</a> .<p>I don&#x27;t use ORM, I use <a href="https:&#x2F;&#x2F;github.com&#x2F;Masterminds&#x2F;squirrel" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;Masterminds&#x2F;squirrel</a> for query building and <a href="https:&#x2F;&#x2F;github.com&#x2F;jmoiron&#x2F;sqlx" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;jmoiron&#x2F;sqlx</a> which helps deals with row&lt;=&gt;struct conversion. For database migrations, I use <a href="https:&#x2F;&#x2F;github.com&#x2F;rubenv&#x2F;sql-migrate" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;rubenv&#x2F;sql-migrate</a> , but if you need an ORM gorm <a href="https:&#x2F;&#x2F;github.com&#x2F;jinzhu&#x2F;gorm" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;jinzhu&#x2F;gorm</a> is OK if you do code first and sqlboiler <a href="https:&#x2F;&#x2F;github.com&#x2F;volatiletech&#x2F;sqlboiler" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;volatiletech&#x2F;sqlboiler</a> is OK if you do database first.<p>For session handling I use scs github.com&#x2F;alexedwards&#x2F;scs , for converting form encoded data to go structs I use github.com&#x2F;gorilla&#x2F;schema, for logging I use zap <a href="https:&#x2F;&#x2F;github.com&#x2F;uber-go&#x2F;zap" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;uber-go&#x2F;zap</a>. For managing roles in an app I use either the voter pattern <a href="https:&#x2F;&#x2F;symfony.com&#x2F;doc&#x2F;current&#x2F;security&#x2F;voters.html" rel="nofollow">https:&#x2F;&#x2F;symfony.com&#x2F;doc&#x2F;current&#x2F;security&#x2F;voters.html</a> in simple cases or casbin github.com&#x2F;casbin&#x2F;casbin . For background jobs I used <a href="https:&#x2F;&#x2F;github.com&#x2F;gocraft&#x2F;work" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;gocraft&#x2F;work</a> and <a href="https:&#x2F;&#x2F;github.com&#x2F;gocelery&#x2F;gocelery" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;gocelery&#x2F;gocelery</a> , for caching i just use redis <a href="https:&#x2F;&#x2F;github.com&#x2F;go-redis&#x2F;redis" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;go-redis&#x2F;redis</a> , for data validation I used <a href="https:&#x2F;&#x2F;github.com&#x2F;asaskevich&#x2F;govalidator" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;asaskevich&#x2F;govalidator</a> or <a href="https:&#x2F;&#x2F;github.com&#x2F;go-ozzo&#x2F;ozzo-validation" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;go-ozzo&#x2F;ozzo-validation</a> . For sending mails to customers I used <a href="https:&#x2F;&#x2F;github.com&#x2F;go-gomail&#x2F;gomail" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;go-gomail&#x2F;gomail</a><p>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:<p><pre><code>    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[&quot;Login&quot;] = append(form.Errors[&quot;Login&quot;], err.Error())
            }
            if err := (requiredValidator{}).validate(form.Password); err != nil {
                    form.Errors[&quot;Password&quot;] = append(form.Errors[&quot;Password&quot;], err.Error())
            }
            return form.getErrors()
    }
    func (form LoginForm) LoginFormView() LoginFormView {
            return LoginFormView{Fields: []Field{
                    {Name: &quot;Login&quot;, Label: &quot;Email&quot;, Type: &quot;text&quot;, Value: form.Login, Required: true, Errors: form.Errors[&quot;Login&quot;]},
                    {Name: &quot;Password&quot;, Label: &quot;Password&quot;, Type: &quot;password&quot;, Value: form.Password, Required: true, Errors: form.Errors[&quot;Password&quot;]},
                    {Type: &quot;submit&quot;, Value: &quot;Submit&quot;, Required: true},
                    {Type: &quot;reset&quot;, Value: &quot;Reset&quot;, Required: true},
            }, Method: &quot;POST&quot;, Name: &quot;LoginForm&quot;}
    }
</code></pre>
Then I can just write an helper in jet to display the the form view:<p><pre><code>    {* tag attributes *}
    {{ block attributes() }}
        {{range .}}
            {{.Key}}=&quot;{{.Value}}&quot;
        {{end}}
    {{ end }}
    {* form field *}
    {{block field()}}
    &lt;label&gt;
        {{.Label}}
        &lt;br&#x2F;&gt;
        {{if .Type == &quot;textarea&quot; }}
        {* textarea *}
        &lt;textarea  name=&quot;{{.Name}}&quot; {{ yield attributes() .Attributes }} &gt;{{.Value}}&lt;&#x2F;textarea&gt;
        {{ else if .Type == &quot;select&quot; }}
        {* select *}
        &lt;select name=&quot;{{.Name}}&quot; {{yield attributes() .Attributes }}&gt;
            {{ range .Options }}
            &lt;option value=&quot;{{.Value}}&quot; {{ if .Selected }} selected {{ end }}&gt;{{.Label}}&lt;&#x2F;option&gt;
            {{ end }}
        &lt;&#x2F;select&gt;
        {{ else }}
        {* basic input *}
        &lt;input type=&quot;{{.Type}}&quot; name=&quot;{{.Name}}&quot; {{ if isset(.Value) }} value=&quot;{{.Value}}&quot; {{ end }}
        {{ yield attributes() .Attributes }} {{ if .Checked == true }} checked {{end}} &#x2F;&gt;
        {{ end }}
    &lt;&#x2F;label&gt;
    {{end}}
    {* form template *}
    {{block form()}}
    &lt;form action=&quot;{{.Action}}&quot; name=&quot;{{.Name}}&quot; method=&quot;{{.Method}}&quot;&gt;
        &lt;fieldset&gt;
            {{ range .Fields }} {{yield field() .}} {{end}}
        &lt;&#x2F;fieldset&gt;
    &lt;&#x2F;form&gt;
    {{end}}
</code></pre>
This is the exact app structure I use to deal with dependencies and filters :<p><a href="https:&#x2F;&#x2F;medium.com&#x2F;statuscode&#x2F;how-i-write-go-http-services-after-seven-years-37c208122831" rel="nofollow">https:&#x2F;&#x2F;medium.com&#x2F;statuscode&#x2F;how-i-write-go-http-services-a...</a>