Blake Mizerany's 2014 dotGo talk totally blew my mind when he showed you don't need gorilla/mux... Now I'm questioning everything. Do we need gorilla/sessions?

agolangf · · 1605 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;ve been doing dynamic routing with the good ol&#39; slice the prefix pattern.</p> <pre><code>func serveProducts(resp http.ResponseWriter, req *http.Request) { key := req.URL.Path[len(&#34;/products/&#34;):] } </code></pre> <p>I&#39;m not totally adverse to dependencies. If I were doing heavy-duty routing that required gorilla/mux, I&#39;d totally go for it. However, at the same time, if the dependency is doing something <strong>trivial</strong> (see example above), then I&#39;d rather avoid possible problems with third-party code I don&#39;t control(/understand).</p> <p>So... Does even Blake Mizerany use gorilla/sessions? What about gorilla/websocket?</p> <p>Talk: <a href="https://www.youtube.com/watch?v=yi5A3cK1LNA&amp;feature=youtu.be&amp;t=11m45s">https://www.youtube.com/watch?v=yi5A3cK1LNA&amp;feature=youtu.be&amp;t=11m45s</a></p> <hr/>**评论:**<br/><br/>kisielk: <pre><p>I&#39;m the current maintainer of gorilla/mux, and even I don&#39;t use it all the time. for most web apps or APIs it&#39;s probably overkill, you only have a few end points. However for larger sets of routes I&#39;ve found it does help keep things organized. </p> <p>Pick the right tool for the job :)</p></pre>joeshaw: <pre><p>I am currently in the process of switching my API handlers from Martini to simply http.ServeMux (and building on top of net/context) and find the code to be so much cleaner and, having an additional 18 months or so of Go experience, less clever. And that&#39;s a good thing.</p> <p>I also decided to go with just http.ServeMux after watching Blake&#39;s talk, but the takeaway I got from it was not &#34;gorilla bad&#34; or &#34;all third party code is bad&#34; but instead that dependencies are not free and you need to think critically about what a dependency buys you.</p> <p>If you really need sessions (and just not a simple cookie), then gorilla/sessions seems like a clear win to me. Is it really a good idea to implement signed values yourself? But if you&#39;re just storing something in a cookie, you don&#39;t need it.</p> <p>I don&#39;t really know enough about websockets implementations to have an opinion here. Is the one in gorilla a clear win over the one in golang.org/x/net/websockets? How about if the one in the net sub-repo were in the standard library?</p></pre>om0tho: <pre><p>Right, I totally agree. Actually, looking at my code, it seems like I use a fair amount of gorilla/sessions, so that one is probably a keeper.</p> <p>However, gorilla/sessions, depends on either gorilla/mux or gorilla/context. The <a href="http://www.gorillatoolkit.org/pkg/sessions#overview">overview</a> says, &#34;If you aren&#39;t using gorilla/mux, you need to wrap your handlers with context.ClearHandler as or else you will leak memory!&#34; This is the only gorilla/context code I use.</p> <pre><code>http.ListenAndServe(&#34;:8080&#34;, context.ClearHandler(http.DefaultServeMux)) </code></pre> <p>Also, what&#39;s up with sub-repo packages? I wonder what &#34;may be developed under looser compatibility requirements&#34; means and if the intention is to one day merge those into the standard library. <a href="http://golang.org/doc/go1compat#subrepos">http://golang.org/doc/go1compat#subrepos</a></p></pre>joeshaw: <pre><blockquote> <p>However, gorilla/sessions, depends on either gorilla/mux or gorilla/context.</p> </blockquote> <p>That&#39;s unfortunate. One of the strengths of gorilla is that it is meant to be small, useful, independent parts you could take or leave. When dependencies like this creep up you start straying into &#34;framework&#34; territory.</p> <blockquote> <p>Also, what&#39;s up with sub-repo packages? I wonder what &#34;may be developed under looser compatibility requirements&#34; means and if the intention is to one day merge those into the standard library.</p> </blockquote> <p>I think that is a possibility, but not necessarily the plan for all sub-repo packages.</p></pre>Artemis311: <pre><p>I think there is a big difference between using a library like Gorilla and a full framework like Martini. </p> <p>Gorilla is a community maintained library just like net/http is a library maintained by the Go team. Either way you are depending on someone elses implementation. The question is if Gorilla offers you the abstraction you are looking for or if net/http offers the abstraction. </p> <p>They are both high quality and I would not say picking one over the other is bad in any way since you are still depending on someone else&#39;s implementation.</p></pre>work2heat: <pre><p>from what I understand, gorilla/websocket is a clear win over the std lib. The std lib does not inherently support keepalives (ping/pong), and I struggled for a while with it before discovering this fact on other forums. I got the gorilla websockets working rather easily without much fuss.</p></pre>ericanderton: <pre><p>I haven&#39;t seen the talk, but from the snippet you posted, that way of doing things is <em>super</em> brittle. A little de-factoring and you can see why:</p> <pre><code>func serveProducts(resp http.ResponseWriter, req *http.Request) { prefixLen := len(&#34;/products&#34;) key := req.URL.Path[prefixLen:] } </code></pre> <p>This doesn&#39;t really match on anything prefixed with &#39;/products&#39;, it matches on a huge number of URLs that happen to have at least as many characters as &#39;/products&#39;. By the time you write in more robust handling of URLs, your program converges on a big router, like Gorilla has. Only with less testing, and more (potential) bugs.</p></pre>fprotthetarball: <pre><p>The serveProducts function is used as the handler for http.HandleFunc, most likely. That would do the pattern matching on the prefix.</p></pre>nstratos: <pre><p>Slicing works great in the case of /products/{pkey} but how about a more complicated case of /customers/{ckey}/orders/{okey}? </p> <p>I try as well to keep as less dependencies as possible in my code but for certain cases I am not quite sure it&#39;s feasible.</p></pre>idkwtfiad: <pre><p>strings.Split(urlstring, &#39;/&#39;) will yield you [&#34;customers&#34;, &#34;{ckey}&#34;, &#34;orders&#34;, &#34;{okey}&#34;]</p></pre>icholy: <pre><p>Here&#39;s how I do it <a href="https://gist.github.com/icholy/dca5b9e079217f7446d1">https://gist.github.com/icholy/dca5b9e079217f7446d1</a></p></pre>nstratos: <pre><p>Thank you. Apparently by adding a little thinking, it&#39;s possible to write simpler code and avoid certain dependencies.</p></pre>Philodoxx: <pre><p>It may yield the same information but I would argue reading <code>/customers/{ckey}/orders/{okey}</code> is much more clear than <code>strings.Split(urlstring, &#39;/&#39;)</code></p></pre>om0tho: <pre><p>Is a little more readability worth a whole other dependency though? Maybe in some cases.</p></pre>Philodoxx: <pre><p>For small projects the split variant of routing is fine. However, as soon as you start dealing with, say, 5+ resources the split version becomes a liability.</p> <p>Rails 3 and 4 have pretty robust and legible routing mechanics, and even then you an end up in situations where it can be hard to find where a route is defined or what parameters you&#39;ll end up with.</p></pre>om0tho: <pre><p><a href="http://www.reactiongifs.com/r/2011/09/mind_blown.gif" rel="nofollow">http://www.reactiongifs.com/r/2011/09/mind_blown.gif</a></p></pre>dotconferences: <pre><p>Glad you liked Blake&#39;s talk! As a small spoiler, he may be back this year on Nov 9: <a href="http://www.dotgo.eu/" rel="nofollow">http://www.dotgo.eu/</a> See you there? :)</p></pre>djhworld: <pre><p>I think most programmers, including myself, are inherently lazy, gluing libraries together gives the illusion of feeling you&#39;re focussing on your domain problem rather than the grunt work that surrounds it.</p> <p>Saying that though I don&#39;t think all dependencies are bad, I mean, writing a SQLite or POSTGRES driver seems like a massive pain in the ass, I&#39;d rather pull that dependency in instead of writing my own. </p></pre>om0tho: <pre><p>I might be the only who thinks this, but laziness is exactly one of the reasons why I don&#39;t like learning frameworks. There are too many to learn and each one has its own patterns and language you must follow. Also, there&#39;s always a hip new framework that you should be using.</p> <p>(Glad I&#39;m not a JavaScript developer! :P)</p></pre>thomasfr: <pre><p>Most packages that can be replaced by a few lines of code usually are not too involved. I usually read everything before i even go get.. sometimes It&#39;s good just for getting design ideas, sometimes I just copy some snippets instead of go getting, sometimes I do go get, sometimes after a while of use I strip away everything I don&#39;t need and integrate the imported package into my application code base.</p></pre>thomasfr: <pre><p>I have found copy/paste/edit/... to be very successful with go. I would not do it with java because of the amount of text and because the internal coupling of stuff makes it not worth the time. I seldom do it in python because of dynamic typing makes makes the process of cutting up something I have not written myself too involved. There are of course other reasons as well.. </p> <p>To me Haskell en Emacs Lisp are two other languages that lends themselves well for efficient copy paste, in the elisp case I guess it has alot to to with emacs being a very specialized domain. </p></pre>_punk_: <pre><p>I&#39;ve used <a href="https://godoc.org/golang.org/x/net/websocket" rel="nofollow">https://godoc.org/golang.org/x/net/websocket</a> and it does the same as gorilla</p></pre>shirro: <pre><p>Many libraries solve non-existent problems and introduce new ones but there are some problems with naively doing everything using standard library with boilerplate code and duplication.</p> <p>For example if you use a switch to decode the method with a fallback for 405 handling that is fine until you decide you want to implement an Allow header or a CORS Access-Control-Allow-Methods header. Then you have to repeat yourself in the default section enumerating the methods you matched in your switch which could introduce errors. This could have been queried from a data structure. Using control structures instead you lost information.</p></pre>DavidDavidsonsGhost: <pre><p>That said I much prefer the &#34;Assert(expected, actual, msg)&#34; pattern, rather then writing an if statement and having msg formatting that the developer feels like.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1605 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传