The standard library is very low level. Want sessions? DIY. Want user auth? DIY. Want CSRF protection? DIY. The list goes on.
It feels like a waste of time implementing these "solved problems" from scratch, but the biggest problem is how easy it is to introduce security vulnerabilities when implementing from scratch, or forgetting to do so.
It’s nice to learn concepts from first principals by using the standard library. But once I know how these things work, I’d rather rely on someone else’s battle tested code and best practices.
Yes, you can add in separate libraries to solve these specific problems, but they are less likely to compose as well as they would in a framework. On top of this, each time you pull in a new library you have to spend time evaluating it. When I use a framework I don't have to think.
This isn't even a new idea. Many Ruby on Rails plugins are actually Rack plugins (even to the point of Rails itself being implemented as a collection of Rack middleware). Rack is the interface that defines how a request is to handled, similar to the Go stdlib interface.
It's definitely true that idiomatic Go tends towards copying being better than dependencies, but the standard interfaces make it much easier to use and swap tried and tested dependencies because they all share the same interface.
Also, here's a list of out-of-the-box library implementations for all the features you mentioned:
Sessions: https://github.com/gorilla/sessions
CSRF: https://github.com/gorilla/csrf
User auth: https://github.com/qor/auth
That's not the sentiment expressed here. To implement these things from scratch is not the only alternative to using a framework.
I also advice any individuals coming from Django or friends to use a web framework.
But after some time spent with the stdlib, and understanding how some of those implementations work, it gets to the point where Id rather not read another set of documentation, learn a new mental model, and deal with bugs. This all comes with a framework.
After awhile you realize that the stdlib provides most of what you need, and that writing more vanilla Go can be simpler then learning a full framework.
I will admit, most my work in Go revolves around internal services, and dont deal with web technologies such as CSRF and CORS. So I do acknowledge my opinion here is leaned toward those use cases.
What you say is true, it's easy to do with stdlib, but it's neither enjoyable not readable. A router lib and a validation lib are realistically still needed.
The same applies for the sql package, it's basically unusable without at least something like sqlx.
This Go enlightment seems to only touch those that don't realize that programming to interfaces was already a thing back in Objective-C and WebObject days, or using Smalltalk categories (later formalized as traits in Pharo).
Also that languages like Java and .NET also have a similar Http server on their standard library since Java 6 (2006) and .NET 2.0 (2002).
The reason we don't use them beyond toy examples, is that they don't scale when things start getting hard and something like IIS, ngix or similar is called into action.
- workload distribution - security and authentication - role management via some form of directory services like LDAP or AD - running tasks in background in response for certain events - mapping into various kinds of databases and information sources - handling caching - have a way to manage reusable components of html/css/js + respective backend code
Yep one can make use of libraries to achieve all of that, but then most likely they don't compose in an easy way, nor make an eco-system.
Hmm? You seem to be mixing two things here. Nobody is suggesting not using NGINX/Caddy etc. The comment was about being able to go very far with just the standard library.
This leads to go web frameworks being sort of semi-hard mountainous turds of code generation. You’ll want to stick to stdlib after sifting through them and deciding they aren’t worth it.
The rest though I do not miss at all. Middleware patching attributes directly into the request object? Python's sad excuse for incremental typing? Ignoring the database bits of Django I struggle to find anything that I don't enjoy doing more in Go. I was a HUGE fan of Django REST Framework and assorted boilerplate for a long time, but I am so extremely glad to be off that ride. Yeah, it lets you do really cool, complex things succinctly and cleverly. The problem is that it lets you do really cool, complex things succinctly and cleverly. The cleverness becomes the enemy. I now have learned to appreciate code that is utterly stupid, obvious, nearly braindead. Every codepath is screaming at you. That is Go in a nutshell. if err != nil { ... } ad nauseam. Sounds terrible... but it kind of isn't.
There are some things I would not use Go for. Game development is one of those things. Web servers, though? If you are going to be doing serious work in production environments, Go is absolutely among the best choices.
I am still, however, looking forward to trying Rust more and more. My initial impressions with Rocket.rs have been lukewarm. (One thing that is bothersome but not quite a deal breaker is compile times. A lot of crates make the experience bad almost immediately.)
I thought RoundTripper was a purely client interface - am I missing something? Servers instead have the base Handler, net.Listeners, ConnState, BaseContext, ConnContext etc.
Youll find that utilizing http Round Tripper along with the Handler interface in the http library will make middleware easy.
Youll eventually dig into filepath and path methods for extracting path parameters from url paths.
And logging and recovery will be a concept youll need to extend outside of just http and into the rest of your application.
I totally advise new comers to use a web framework, but in the long run, you probably wont want too.