
Show HN: A simple Go web server with logging, tracing, health check - enricofoltran
https://gist.github.com/enricofoltran/10b4a980cd07cb02836f70a4ab3e72d7
======
Xeoncross
Can someone add letsencrypt.org ACME cert generation?
[https://godoc.org/golang.org/x/crypto/acme/autocert](https://godoc.org/golang.org/x/crypto/acme/autocert)

Edit: found this
[https://gist.github.com/kennwhite/f9ea1afff776049974678fb21a...](https://gist.github.com/kennwhite/f9ea1afff776049974678fb21a6f3846)

~~~
Xeoncross
I went ahead and started fleshing out a combination of both of these along
with an example of using golang templates:
[https://github.com/Xeoncross/vanilla-go-
server](https://github.com/Xeoncross/vanilla-go-server)

------
rcarmo
This reminds me of an ongoing discussion I was having with friends about
Golang web frameworks -- one side of the argument is that you can achieve so
much with the standard library that frameworks are "unnecessary", but folk
like me want an ORM(ish) layer and some kind of back-office scaffolding.

[https://beego.me](https://beego.me) and [https://iris-go.com](https://iris-
go.com) are nice, but we (all) have (as yet) to find a Django-like framework
that comes with an extensible back-office.

So... Any pointers on the latter? I can do an Ask HN, but this seems like a
good context to ask in.

(Edited to add: why the downvotes? Is this not a legitimate question?)

~~~
bsaul
I regularly go down this road with go. My conclusion is that it's never going
to suit that use case. I'm not even sure it's not technically doable (i think
introspection and interface{} can go quite far), but it's just culturally
opposed to this kind of project.

People like go for its minimalist approach. Not in the sense that you don't
have a lot of code to write, but more in the sense that you are in control of
everything that happens, and that you can read an understand every part of
your codebase.

ORMs , code gen, magic wrappers, etc is something that people in that
community just hate.

~~~
dy
I’m the same way - I have lots of side project ideas I’d love to use Go for
but get that early Rails like productivity. I maintain a few Rails apps and
now view many of the things I’ve done as hacks to work around the lack of
concurrency (though that was just Rails’ reality in late 2000s).

Elixir is close to my ideal though I like static types and a better community
around libs would be nice.

~~~
billhathaway
You might be interested to check out
[https://gobuffalo.io/](https://gobuffalo.io/)

------
twic
Here's a quick attempt at the same thing in Java (although note that the
command line format is different):

[https://gist.github.com/tomwhoiscontrary/b4888b86057c74a636c...](https://gist.github.com/tomwhoiscontrary/b4888b86057c74a636c455235c756354)

The main takeaway is that the JDK's built-in web server is poor:

* There is no way to configure timeouts

* Filters have to be added to each handler separately, by mucking with its filter list

* Filters have to extend an abstract class with two methods (one totally pointless), so you can't use lambdas for them

* Handlers use a simple string prefix match, so a request for "/healthzone" will hit the health handler

* The stop method always blocks for the specified timeout, and never returns early as the docs promise (IME)

Other minor irritations:

* There is no method to parse an InetSocketAddress from a string

* Java's support for handling clean process shutdown is not great; i think there's some sort of race between the shutdown hook and the logging system getting shut down, so you never see the "Server stopped" message

~~~
skanga
Nice. Does anyone have a server like this but with the addition of

* serving of files and directories

* LetsEncrypt certificates and SSL

~~~
wyattjoh
The builtin golang.org/x/crypto/acme/autocert [0] package manages SSL for you
easily through Lets Encrypt.

[0]:
[https://godoc.org/golang.org/x/crypto/acme/autocert](https://godoc.org/golang.org/x/crypto/acme/autocert)

~~~
TheDong
golang.org/x/ packages are _not_ builtin. You still must download them and use
them just as you do any other dependencies, they just share some contribution
process and developers with golang's stdlib.

------
oppositelock
It's a nice reference program to show you what's going on.

I build stuff like this for a living. I'd recommend not re-inventing the wheel
yourself and using a nice web framework, like Echo
([https://github.com/labstack/echo](https://github.com/labstack/echo)) or Gin
([https://github.com/gin-gonic/gin](https://github.com/gin-gonic/gin)). I
prefer Echo due to a cleaner, mockable design, but they're equivalent.

You can throw up that web server in 1/10 the code to do the same thing, and
using built-in middleware is less work than writing your own.

~~~
dstroot
I tend to agree and I’d throw Chi in the mix. I like Chi quite a bit. Or, use
the Gorilla components and middleware.

~~~
pdappollonio
I also use Chi a lot and Chi and this example are actually complimentary: you
can take the Chi router and pass it to an http.Server in the handler attribute
to make it work.

------
akditer
Golang is self sufficient for a small scale web app.

It has HTML templates library, decent error handling, rpc, logging, built-in
http server. Many people choose golang for that reason.

~~~
sethammons
What do you mean by small scale? I think requests per second. Our Go-backed
API has handled 90k rps without batting an eye. Or do you mean small scale as
in team size? It is my understanding that Go was specifically designed to work
for large organizations ( _cough_ Google _cough_ ).

Or do you mean single page JavaScript web sites? At which point Go would be
the backing API? I don't see what qualifies Go for "small scale" vs "large
scale."

Thanks for any clarification. Cheers!

~~~
Liru
I would say "small scale" would refer to project size in Go.

~~~
sethammons
Thanks

------
AndrewStephens
Thanks for this. I have been writing toy golang servers for a while to try out
various ideas and this really helps clarify some useful techniques and best
practices.

------
grzm
This is likely better posted as a Show HN if it meets the guidelines:

[https://news.ycombinator.com/showhn.html](https://news.ycombinator.com/showhn.html)

~~~
enricofoltran
Hi grzm, you are probably right. Can I do this myself? editing the title with
a "Show HN" prefix is sufficient?

~~~
grzm
The ability to edit submissions is time-limited, IIRC. If you no longer see an
edit link, you're likely outside of it. You can get in touch with the mods via
the Contact link in the footer and they can update it for you. In my
experience they're quite responsive.

------
Ultimatt
So a hundred lines of pure boilerplate hooking up Go standard libraries,
assumedly exactly how they were intended to be used. How is this news worthy?

~~~
enricofoltran
Hi Ultimatt, this is just a reminder for me on how to do those things when I
start a new app in Go, instead of always google for them. Didn't expect to hit
the homepage!

------
MrF3ynmann
Yea lets ditch everything we learned about modularization in the past 20 years
and put everything in one single binary

~~~
eeZah7Ux
Having to rebuild thousands of binaries every time a vulnerability is found in
a popular library is seriously hurting Linux distributions.

That, and having to handle vendorized dependencies.

~~~
rhencke
> Having to rebuild thousands of binaries every time a vulnerability is found
> in a popular library is seriously hurting Linux distributions.

Do you have a source for this?

------
coldcode
Isn't Caddy written in Go? How is this different?

~~~
mholt
When you're writing a Go application and want just a few things out of a web
server, something like this is a nice demonstration on how to do that with a
few lines in your Go program. Yes, you could use Caddy, or you could even
import it and use it as a library; but if you prefer something like this,
there you have it.

------
chrisper
I do not quite see the point of this (other than being an exercise).

We already have web server that do "logging, tracing, health check, graceful
shutdown." I do not care about zero deps, because I only install them once and
the deps are taken care of by the package manager.

In my opinion, the Go web server only makes sense as part of a Go application
as a whole. But a standalone Go web server does not make much sense to me.

~~~
sergiotapia
I disagree, I will always prefer projects with the least dependencies given
two options with the same feature set.

We should always try to strive to lower dependencies when it makes sense.

~~~
allover
> We should always try to strive to lower dependencies when it makes sense.

Maybe, but I think 'when it makes sense', might be 'rarely'. There a 2 ways to
avoid dependencies: 1. lean on a batteries-included standard lib as this gist
does or 2. write it yourself.

Problem with 1. is standard lib libraries aren't always great, see 'where
modules go to die' [1], (examples: httplib/urllib in Python, or the string
libraries in PHP). This can stifle innovation and alternatives, unless an
alternative with a strong marketing push can arise ('requests' for Python).
Sadly, often because the situation isn't 'that bad' (as in the case of PHP)
people continue to use poor APIs.

Problem with 2. is you're probably getting an order-of-magnitude fewer brain
cycles on code you wrote yourself -- unless you can spend the extra effort to
open-source it, and get lucky with popularity/contributors, it's likely to be
inferior than a well-maintained 3rd party alternative.

[1] [http://www.leancrew.com/all-this/2012/04/where-modules-go-
to...](http://www.leancrew.com/all-this/2012/04/where-modules-go-to-die/)

~~~
013a
You spend brain cycles trying to navigate and integrate third party libraries,
learning their APIs, keeping the dependencies updated.

I'd encourage developers, especially Nodejs devs, to look at their list of
dependencies and ask the following two questions about each of them:

1\. How long would it take me to replicate this functionality?

2\. How often does this functionality need updating?

There is a threshold balanced between both of those questions where, once the
numbers pass, it makes sense to bring in dependencies. But I truly believe the
"instant gratification" primate part of our brains tends to overestimate the
benefit of dependencies and underestimate the long term negatives of them.

Here's a common Nodejs example: Request. Request is used all over many
projects. Did anyone who imports it even try to use http.request in the nodejs
stdlib? Its actually pretty great. Now, you introduced a new dependency. You
made your build process longer. You made your deploy artifact bigger. You've
got to keep it up to date. You've got to make sure there aren't security
breaches. You've got to learn a new API that, unlike the Nodejs stdlib, is
just made by "some guy somewhere" and is horribly documented inside a Github
README.

How long would it take me to replicate the functionality of request just using
http.request? It depends what parts of request I'm using, but probably very
little time. How often does this functionality change? Literally never.
__Literally never __. HTTP /1.1 was finalized decades ago. Request, right now,
has 48 open PRs, 560 open issues, was last "released" a couple months ago, and
was fixing security issues which were definitely already fixed in stdlib.

But the primate part of your brain says "Eh fuck all that, I'll let future
self deal with the negatives of a new dependency, what I want _today_ is an
API interface that's, like, 20% easier to use."

