TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Writing HTTP Middleware in Go

112 pointsby babawereover 11 years ago

4 comments

optymizerover 11 years ago
<p><pre><code> &gt; a painless and even fun process </code></pre> This claim might be a little too optimistic. I&#x27;d like to challenge you (everyone) to associate a User object with an http.Request. Example code in Node.js&#x2F;ExpressJS:<p><pre><code> function auth(req, res, next) { req.User = User(&quot;username&quot;); next(); } </code></pre> This is such a simple example of a useful piece of middleware, yet it is so difficult to implement in Go in a &#x27;painless and fun&#x27; way.<p>I would prefer to avoid contention on a global mutex.<p>I would prefer to keep the compatibility with http.Handler and http.HandlerFunc.<p>Good luck!
评论 #6871834 未加载
评论 #6871403 未加载
评论 #6871365 未加载
评论 #6871729 未加载
评论 #6874963 未加载
bfrogover 11 years ago
The request context is I think the most annoying part of go http handling.<p>Oh you want to wrap your handler with something that does db.Begin()&#x2F;db.Commit()? Well you need to stuff that tx somewhere...<p>so then your options are a global map[*http.Request]interface{} with mutexes or pass it as an arg. Passing it in as an arg means you either lose compile time type checking because you use reflect or lose the ability to add more middlewares that build up request context. The map[]interface{} also loses compile time type checking for the most part unless you do something per type of context, with more mutexes.<p>The second option is the sanest, but means either reflect if you have more than one context arg to build out (sql.Tx + cache + oauth grant + whatever else maybe?) or you have some common context object that may or may not use everything every request and your just adding more context members all the time that may or may not be initialized for that particular request.<p>Sometimes I miss the dynamic typing and&#x2F;or compile time type templating.
评论 #6870928 未加载
评论 #6871477 未加载
latchover 11 years ago
I find the use of httptest.ResponseRecorder as well as the proposed context pattern not very elegant.<p>Just because go&#x27;s HTTP entry point is an http.HandlerFunc, doesn&#x27;t mean your middleware need to implement that same method. I&#x27;d prefer:<p><pre><code> type Middleware func(context *Context) Response type Context struct { Req *http.Request Token string } type Response interface { Status() int .... } </code></pre> No global variable, and definitely no contention against that global.<p>(note, I&#x27;d make the middlewares nesteable, passing a next middleware to each middleware, but that wasn&#x27;t covered in the article).
评论 #6869983 未加载
tedchsover 11 years ago
In the Ruby community, the Rack interface has done a lot to enable Web middleware to work together. It would be great if there were an analogous interface for Go&#x27;s net&#x2F;http.
评论 #6870919 未加载