
Writing web applications using only the Go Standard Library - xorbox
https://golang.org/doc/articles/wiki/
======
brian-armstrong
I'm a big fan of this approach. Idiomatic Go often means doing things in an
explicit manner. Consider how error checking works, for example.

I've tried a few of the Go web frameworks and it feels like they often add a
lot of indirection. It's appropriate for Python or Ruby, but it feels out of
place in Go. Yes you might cut out a little repetitious code but DRY doesn't
seem to be a key pillar of the Go language

~~~
transitorykris
Go's standard library is excellent. I've found Gorilla Mux to nicely augment
net/http and not feel like I'm wrapping magic around idiomatic Go. The only
other 3rd party package I routinely use is sqlx.

[http://www.gorillatoolkit.org/pkg/mux](http://www.gorillatoolkit.org/pkg/mux)

[https://github.com/jmoiron/sqlx](https://github.com/jmoiron/sqlx)

~~~
notheguyouthink
I literally found out about sqlx a few moments before coming here. I was
stringing together ~10 columns by hand, and then when i fed them into the
`row.Scan()` method, i just about rage quit. On Monday i'm going to try
integrating sqlx and see how i like it.

Any other good sql libs i should know about? My coworkers mostly like sql by
hand, so no magic ORMs preferably. But unmarshalling rows seems like an
absolute requirement.. this is just anarchy without it.

~~~
bitexploder
Gorm. Give it a try. Light on magic. Can write by hand easily still. If you
arent writing really complex queries and are just shuffling records around
Gorm makes life a joy. It is no SQL alchemy but for most SQL users ORM/SRM
makes life better. Anyway I think most systems using SQL in business logic end
up implementing a relational mapper, just not as well as battle tested
mappers. But some use cases do justify avoiding such tools.

------
Elrac
Here's a tribute to the tutorial as such, independent of the topic:

After having consumed thousands of tutorials, I found this one exceptionally
lucid and instructive. Kudos to the author!

His approach of stepwise expansion and refinement lets him introduce feature
after feature without the whole thing looking stilted or shopping-list
cluttered. For each feature, he shares an itch with the reader and then
scratches it. This keeps the reader interested and motivated.

Here, at least in my opinion, is a style and an approach that other tutorials
would do well to emulate.

------
shadowmint
Look, I'm a big fan of go; I like the language, I (mostly) like the community,
and I've seen some excellent stuff built in it.

...but, this 'dont use anything but the standard library' movement that keeps
popping up here and on reddit is just ridiculous.

It's just fall out from people who can't _be bothered_ figuring out how to use
3rd party dependencies.

No matter how amazing and excellent your language development team is, the man
power of work in the wider ecosystem is significantly larger, and avoiding the
work done by others to 'hand roll' your own solution is not the answer.

Yes; learning frameworks is tedious.

Yes... sometimes someone elses 'style' of code might not match yours...

...but, you have to ask yourself: are you writing code as an intellectual
exercise, or trying to build something?

Because, if you're trying to build something, and you want to write every
little piece of it yourself; you'll never build it.

This is the same (daft) argument as people suggesting they build their own
game engines.

Building websites isn't trivial; and there are parts you need to do it aren't
in the standard library, and never will be (eg. redis, memcache,
elasticsearch, aws, grpc, the list is endless).

I appreciate the simplicity of just 'standard library only' to get started,
_realistically_ , is it meaningful to talk about?

I doubt you'll ever write a service that is 'standard library' only.

~~~
PaulRobinson
So, first of all, for the examples you cite - reds, memcache, elastic search,
aws, etc. - I have never, ever seen a member of the Go community say "don't
use a library".

The Go community is anti-framework, not anti-library.

And what's the problem with frameworks? Well, remember up until now most Go
shops (including my own), are micro-service orientated. You want small,
lightweight, high-performance services. Why would you want or need a large
monolithic bag of tricks in there? If you need complex routing, are you sure
it's a micro-service? If you can't keep track of the datastore and need an
ORM, are you sure it's a micro-service?

Also, it's a discipline, not a requirement. In the same way other languages
have their idioms (I'm a Ruby dev of 10+ years experience too - those idioms
are baked in _hard_ for me), Go's idioms are around structure, performance,
and what is reasonable to write at a larger level.

Should you use libraries in Go? Yes. Should you use frameworks? Nobody is
stopping you, but are you sure Go is the right place for you and your
monolithic application?

Also, I don't see a problem with the official Go website having a tutorial in
Go using the standard library. Why would they not?

~~~
crdoconnor
There's multiple good reasons for using a framework.

1) It enforces appropriate design patterns for the task at hand.

2) It produces code structures that are standardized rather than idiomatic.

3) It provides a superstructure that allows the integration of a variety of
different plugins without having to write a lot of boilerplate.

I've no doubt this applies to go as equally as it applies to any other
language.

That said, bad frameworks (which is most of them) are often worse than none at
all.

~~~
PaulRobinson
I don't think you read my comment, or at least if you did, you didn't
understand the point I was making.

Micro-services are the appropriate design pattern that means frameworks are
redundant in a micro-service architecture.

Code structures do not need to be standardised in a service you can read the
entire source code to in 20 minutes and replace in a few days if you need to.

Micro-services do not want or need the integration of a variety of plugins,
and little to no boilerplate is required.

------
candiodari
This is extremely, extremely bad advice. Do NOT run code like this, ever,
exposed to anything, not even your own internal network. This is just
ridiculously risky.

This gets you code generating html pages. It doesn't store anything. It
doesn't do anything. It doesn't create any relation between any data and what
is on screen. It stores things extremely insecurely (it can probably overwrite
the application serving this with random binary data, trivial to privilege
escalate (just overwrite the application itself)). It's slow, no caching
layer, no ... It can't work, really, without tons of extra code. And it
doesn't support all sorts of necessities of today's web apps. No auth, no
users, no client identification, not even bloody cookies (although yes, all of
those are doable with extra code). There's nothing in front of the
application, allowing you to serve multiple applications.

This does:

    
    
        filename := title + ".txt"
        body, err := ioutil.ReadFile(filename)
    

(with filename taken directly from the url. It then proceeds to ignore any
error upon loadPage return ... well done !)

(I _love_ how the code making an extreme security error of using unchecked
pathnames includes a discussion about exactly what permissions to use in the
open call to open that file. Talk about missing the forest for the trees)

Just found a way to crash the application : just upload an invalid template,
because the error is ignored on the template parsing, which can NULL the
pointer the template, which will panic the app upon rendering the template.
Hell, you're pretty much bound to do that by accident.

Please, people: DO NOT run code like this, unless you want to run a bitcoin
miner for someone else, an illegal file mirror, or worse. For the love of God,
do NOT give code on the same server any payment details for your web app and
do NOT run this behind a firewall, or within your amazon virtual private
cloud.

This brings back the very bad old days of C code serving webpages: so
exploitable you're bound to exploit it by accident (ie. crash it). And it
doesn't even have the good parts of the old C code : this thing uses
introspection, which will make rendering templates about as fast as in python
or ruby.

~~~
banku_brougham
can anyone else comment here on the stated un-safety of using this web app
tutorial? I have no idea, but it seems like a good tutorial and it is posted
on the official golang.org site. Can it be as bad as candiodari says?

------
bacongobbler
Is this a new wiki page? I've seen bits and pieces here and there in the
net/http docs but nothing nearly as extensive.

I think the stdlib is awesome, but the biggest gripe I have with the standard
net/http library would be the multiplexer (ServeMux). Out of the box if you
provide it with a handle like /foo but the user making a request adds a
trailing slash (e.g. GET /foo/), it returns a 404, compared to other libraries
like julienschmidt/httprouter which will handle cases like this for you.

For example:
[https://play.golang.org/p/Q96EulBUfI](https://play.golang.org/p/Q96EulBUfI)

Other than that I think the stdlib is bang-on for simple http servers.
Wouldn't recommend it if you're planning on writing a web server backed by a
database, however. Compared to other web frameworks like django, the stdlib is
a great library for working at a lower level in the stack, whereas Django is
more of a content-oriented framework built around higher level concepts like
basic CRUD applications.

~~~
eternalban
I think Go is being strictly correct here:

[https://play.golang.org/p/eSDl2MuFdP](https://play.golang.org/p/eSDl2MuFdP)

~~~
codebeaker
Isn't being "technically" correct, but actually not doing what people expect
kinda frowned upon?

> Be conservative in what you do, be liberal in what you accept from others

[1]:
[https://en.wikipedia.org/wiki/Robustness_principle](https://en.wikipedia.org/wiki/Robustness_principle)

~~~
jasonkostempski
I despise that quote. Regardless of what the intended message was, what it
implies is a horrible recipe for life-long support of shitty client behavior.

------
Animats
The good thing about Go's standard library is that Google uses it internally.
Thus, it's well-exercised. It's probably been run on a bigger load than yours.
That's valuable.

------
lopatin
For me the biggest value they contributed with the Go standard library is the
interfaces they baked into it, not necessarily the default implementations of
them (no complaints there of course). They modeled the way that servers are
built as interfaces, and if someone builds a 3rd party lib (like "mux",
mentioned here in the comments), usually they implement the interfaces defined
in the standard lib and they become a drop in replacement to the default
implementation. I wish more SDKs were built like this.

------
gleenn
"If your life is too easy and you want to create a never ending stream of
tears and frustration you can try and inline the CSS that applies to elements
above the fold and have the rest load in a separate CSS file."

Good read, not a ton of practical advice though.

I got a good laugh honestly. Nice article which is filled with interesting,
although not necessarily useful performance ideas. Their site does load
impressively fast at ~10ms page-load reported by Chrome.

Unfortunately, as a professional web developers, my clients _never_ need such
optimizations. They want new features long before they ever get upset about
pages being sluggish in the second range. I'd love to be required to do more
stuff like this, and I'm sure some people do, but the vast majority of the
suggestions are looking for performance at all costs.

~~~
hurricaneSlider
think you're commenting on the wrong article

------
thewhitetulip
I've written a tutorial on writing webapps without using a framework!

[https://github.com/thewhitetulip/web-dev-golang-anti-
textboo...](https://github.com/thewhitetulip/web-dev-golang-anti-textbook)

PDF: [https://leanpub.com/antitextbookGo](https://leanpub.com/antitextbookGo)

------
mariocesar
I'm trying to make a similar for python, I knew it will not be as easy to
start, Go standard libraries are more featured that the ones in python for the
Web.

[https://github.com/mariocesar/wiki.py](https://github.com/mariocesar/wiki.py)

------
biztos
I've been working on a Go web server I hope to open-source (as soon as it's
any good) and it occurred to me that one big advantage of using only the
standard library would be in licensing. As long as your own license is the
same as Go's (BSD IIRC) you present an unambiguous picture to anyone wanting
to use the software.

In the end I think I'll use a few external packages and just expose the
licenses in the app, but I'm doing this primarily for myself. If I were making
something I expected to be in wide use I would seriously consider sticking to
the standard library just for that clarity.

------
dmux
There was a discussion about Racket and its documentation yesterday. This is
exactly the style of tutorial that they need.

------
realstuff
"Yeah, yeah, but your scientists were so preoccupied with whether or not they
could that they didn't stop to think if they should.

~~~
jerf
Most, if not all, languages that work on the server side eventually develop a
"minimalist" "web framework" in reaction to the "bloat" of some popular fully-
feature one. Particularly coordinated languages even eventually develop a
barebones server backend that allows you to potentially even plug them
together, like Python's WSGI.

Generally these frameworks are met with general acclamation on HN. (Followed
by a lot of replies generally defending the larger frameworks, which then
devolve into a couple of threads about how hard it is to pack resources
together, the importance of a "blessed" ORM, and the security implications of
requiring people to assemble their own security stack for things like CSRF,
etc.)

Are they less worthy if they're simply built into the language from day one? A
lot of recent languages are taking such a tack, after all.

------
zzzcpan
Note, that this is not how anyone should actually write web applications in
Go. Standard library doesn't have production ready defaults, in some cases
even lacks options for that, and generally offers bad choices in terms of
abstractions and performance. And as complexity of your app increases you are
going to suffer the consequences.

Safer road for a webapp is to start from a net.TCPConn kind of server with
your own tiny HTTP/1.0 parser and a tiny templating engine, your own or a 3rd
party one (it's absolutely not hard). Pay attention to synchronization,
packages that do implicit synchronization are better left to their owners,
avoid unnecessary accidental complexity like that.

(Go user since Go 1.0, speaking from the experience)

~~~
bacongobbler
Can you elaborate more on some of those production ready defaults the stdlib
doesn't have? Genuinely curious.

~~~
shadowmint
[https://blog.gopheracademy.com/advent-2016/exposing-go-on-
th...](https://blog.gopheracademy.com/advent-2016/exposing-go-on-the-
internet/) covers a number of issues that should be considered.

------
austincheney
I am a bigger fan of the keep it simple approach, which is my way of saying I
prefer to write web applications in the web technologies directly intended for
the given task.

I suspect Go is a newer and better language than Java, but this soooo reminds
me of Java devs trying to do everything web related in Java. Ohhhh the pain
and torment (guessing, apathy, and crying about how horrible things like
markup and JavaScript are because they simply aren't Java).

~~~
ternaryoperator
> Ohhhh the pain and torment (guessing, apathy, and crying about how horrible
> things like markup and JavaScript are because they simply aren't Java).

Almost everyone complains about JavaScript, and very few of the folks I hear
complain about it wish it were more "like Java."

~~~
cblock811
I've never heard anyone say they wish JavaScript were more like Java. Can you
tell me more about why they say that?

~~~
c_shu
I wished I could have `for...of` loop to iterate array in javascript, so I can
say goodbye to `for(var i=0;i<len;i++)`. Now it's supported by all browsers.
But it's so late. You cannot use it unless you only support very recent
browsers.

~~~
ludamad
Not true, you can use typescript and have it along with stays-out-of-your-way
static typing, or only test in modern browsers and cross compile later.

~~~
c_shu
That's another language. You can prefer Java. You can prefer TypeScript. They
are just not JavaScript. (Nowadays there are so many source-to-source
compilers to JavaScript. Even Java-to-Javascript compiler.)

~~~
ludamad
What additions that TypeScript has do you find offensive? And that's why I
gave my second option, which allows you to use modern JavaScript natively
(without the additional features TypeScript has, if so opposed) and cross-
compile when you have to target older platforms.

