<p>http.ServeMux is a good example.</p>
<p>Edit: Yea, I'm Unsubscribing from this sub. Even reasonable opinions of mine are just being down voted, and it looks like I'm being personally insulted too. This isn't supposed to be <a href="/r/politics" rel="nofollow">/r/politics</a></p>
<hr/>**评论:**<br/><br/>neoasterisk: <pre><p>This fud that <code>http.ServeMux</code> is not good enough or even bad, needs to stop.</p></pre>burtgummer45: <pre><p>So how do you do params?</p></pre>shovelpost: <pre><p>Here's <a href="https://youtu.be/yi5A3cK1LNA?t=11m44s" rel="nofollow">a way to do it</a>. In case you do not recognize the speaker, he is the creator of <a href="https://github.com/bmizerany/pat" rel="nofollow">pat</a>, a small but still popular http muxer which he admits he doesn't use anymore.</p></pre>burtgummer45: <pre><p>Thanks, that convinced me to never use http.ServeMux</p></pre>shovelpost: <pre><p>How so?</p></pre>burtgummer45: <pre><p>Lack of features? </p></pre>shovelpost: <pre><p>You fall into the fallacy described in the video as Predetermination. You have already decided that you will forever use an external router because <code>http.ServeMux</code> "lacks features". This is not what I would call good engineering. </p>
<p>Wise words by <a href="/u/carsncode" rel="nofollow">/u/carsncode</a>:</p>
<blockquote>
<p>My general recommendation though would have to be: don't take on dependencies unless you have to. The standard library is very broad, the language is very easy to work with, and personally I think the import-happy culture of NodeJS, .NET, Java, Ruby, and so on is a plague on software development. We're in dire need of a move toward fewer dependencies and better-vetted dependencies.</p>
</blockquote></pre>burtgummer45: <pre><blockquote>
<p>You fall into the fallacy described in the video as Predetermination. You have already decided that you will forever use an external router because http.ServeMux "lacks features". This is not what I would call good engineering.</p>
</blockquote>
<p>I know I need url parameters, I need to group routes together and apply middleware differently to each group, and I want easy subrouter mounting so I can compose my app in smaller pieces and plug them together. It looks like if I used http.ServeMux I'd have to reimplement this all myself, so I'm going with chi.</p></pre>shovelpost: <pre><p>Sure, use whatever makes sense for your project's requirements. But saying "I'm never using http.ServeMux" without talking about the project's requirements is not very good.</p></pre>burtgummer45: <pre><p>I doubt I'll ever use http.ServeMux, its just too limited, even crippled. A router that makes me handle params manually? You'll never convince me that's a good idea.</p></pre>shovelpost: <pre><blockquote>
<p>http.ServeMux is a good example.</p>
</blockquote>
<p>Is it? Maybe I am alone in this but I've been using ServeMux for years and I've had no issues.</p></pre>burtgummer45: <pre><p>I got the impression that it cannot do parameters, doesn't do the subroute composable thing, and performs pretty bad compared to everything else, if that matters.</p></pre>dgryski: <pre><p>In all my years writing high performance services in Go I've not once seen HTTP routing show up in my pprof output.</p></pre>losingthefight: <pre><p>I would agree. DB Access, I/O, network calls, etc tend to be far more draining on performance than a good HTTP router. I mean, I don't use the standard router, but I haven't encountered a situation in which the router was my bottleneck. </p></pre>burtgummer45: <pre><p>I don't doubt it, thats why I wrote "if it matters", but don't you agree that if you want params you need to use something else, or did I miss something?</p></pre>: <pre><p>[deleted]</p></pre>umadbrobot: <pre><p>"Mouth breather. "</p></pre>dlsniper: <pre><p>If it matters, everything else except fasthttp is literally built on top of net/http.ServeMux.</p>
<p>So... I'm not sure to what you are talking about when you say it's performing pretty bad comparing to the everything else (which is built on top of it), but I'm sure you've got your facts wrong.</p>
<p>The only issue with net/http is that it doesn't have a convenient way to handle the various routing other packages depend on, and you'd need to build your own router every time. See an example here: <a href="https://blog.merovius.de/2017/06/18/how-not-to-use-an-http-router.html" rel="nofollow">https://blog.merovius.de/2017/06/18/how-not-to-use-an-http-router.html</a></p>
<p>And to add to dgryski's user report, I too have never experienced issues with the http performance in Go, mainly because by the time a real app gets to be used, I run out of network bandwidth, memory, performance on the dependency services (which usually have the similar recursive problem), etc.</p></pre>: <pre><p>[deleted]</p></pre>pdffs: <pre><p>It's better in that it actually functions correctly, but I'd argue that the <code>io.ReadWriter</code> API of <code>x/net/websocket</code> is often preferable.</p></pre>: <pre><p>[deleted]</p></pre>pdffs: <pre><p>Being able to treat a websocket like any other socket means that it can be used with any library that can work with the <code>io</code> interfaces, rather than having to build bespoke message-based code. Websocket is kind of a weird spec - it's actually a stream of frames, with message semantics layered on top, providing both APIs would be preferable IMO.</p></pre>losingthefight: <pre><p>I am primarily a web API developer and microservices systems architect, so I have a biased opinion. Two right off the bat I cannot live without:</p>
<p>github.com/stretchr/testify/assert
Being able to assert on various conditions makes things SO much nicer and cleaner.</p>
<p>github.com/jmoiron/sqlx
NamedExecs, auto-scanning, and more makes this a dream to work with. Database access has been far more elegant.</p>
<p>I also love Chi, but enjoyed Gin and Gorilla.</p></pre>fourgbram: <pre><p><a href="https://www.github.com/jmoiron/sqlx" rel="nofollow">sqlx</a> has been very helpful. Without it, while fetching data from my database, I'd have to make variables for each column, with the same name as the column in the DB, and then scan into those variables.</p>
<p>Without sqlx:</p>
<pre><code>query := "SELECT username, userage, userheight FROM person"
rows, err := db.Query(query)
//do error checking here
var username, userage, userheight string
for rows.Next(){
err = rows.Scan(&username, &userage, &userheight)
}
</code></pre>
<p>With sqlx:</p>
<pre><code>type Person struct{
var name string `db:"username"`
var age string `db:"userage"`
var height string `db:"userheight"`
}
rows, err := db.Queryx(query)
var p Person
for rows.Next(){
err = rows.StructScan(&p)
}
</code></pre>
<p><code>StructScan()</code> is super helpful.</p></pre>losingthefight: <pre><p>Or even better:</p>
<pre><code>type Stuff struct {
ID int64 `json:"id" db:"id"`
UserID int64 `json:"userId" db:"userId"`
SomeField int64 `json:"someField" db:"someField"`
}
func GetStuff() ([]Stuff, error) {
stuff := make([]Stuff, 0)
err := Config.DbConn.Select(&stuff, "SELECT * FROM Stuff")
return stuff, err
}
</code></pre>
<p>edit: code formatting</p></pre>fourgbram: <pre><p>Wow, didn't know that one. Thank you. </p></pre>
![](https://static.golangjob.cn/static/img/banner.png)