Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

There's an almost pathological resistance to using anything that might be described as a 'framework' in the Go community in the name of 'simplicity'.

I find such a blanket opinion to be unhelpful, what's fine for writing microservices is less good for bootstrapping a whole SaaS app and I think that people get in a bit too much of an ideological tizz about it all.



I don't think anyone would advise to do everything from scratch all the time.

It's mostly about libraries vs opinionated frameworks.

No one in their right mind would say: just use the standard library but I've seen it online. That discourse is not helping.

I think people get this miscontrued on both sides.

A set of reusable, composable libraries would be the right balance in Go. So not really a "framework" either.

I think that reflects better the actual preferred stance.


It's always going to be more work with composable libraries since they don't 'flow'.

Just picking one of the examples I gave, pagination - that requires (a) query param handling (b) passing the info down into your database query (c) returning the pagination info in the response. In Django (DRF), that's all built in, you can even set the default pagination for every endpoint with a single line in your settings.py and write no more code.

In Go your equivalent would be wrangling something (either manually or using something like ShouldBindQuery in Gin) to decode the specific pagination query params and then wrangling that into your database calling code, and then wrangling the results + the pagination results info back.

Composable components therefore always leave you with more boilerplate


I guess there are pros and cons. Pros of composable libraries is that you can more easily build upon them for your specific use case.

It also doesn't tie you to ORM usage.

You have to be responsible for "your" specific flow... meaning you can build your own defaults easily wrt parsing query parameters and whatnot (building a generic paginated query builder API?). Nothing insurmountable.


That's fine as long as you never need to deviate from the default behavior of the framework.


Fortunately the framework is pretty configurable on all this sort of stuff! Just to hit pagination again since it's the example I've used in other comments, in DRF you implement a custom pagination class:

https://www.django-rest-framework.org/api-guide/pagination/#...

That's the same as for most other configurable things. And ultimately if you want to override the behaviour for some specific endpoint then you can still easily do that by just implementing your own method for it.

After working in Go now for several years, what I've found is that generally people just don't some things in their first pass because it's too much work and makes the PRs too large, and then they retrofit it afterwards. Which meant that the APIs were less consistent than the ones I worked on in Django.


> No one in their right mind would say: just use the standard library but I've seen it online.

Yes but...sometimes the proper level of abstraction is simply a good HTTP library. Where the API of your application is defined in terms of URLs, HTTP methods, status codes, etc., the http library from the Go standard library might be all you need (depending on other requirements, of course).

A real life example: I needed a simple proxy with well defined behavior. Writing it in Go as a web application that forwarded calls to another service based on simple logic only took a few pages of code in a single file.


I don't dispute that. But in general you need sessions, you need a few middleware to, for example, handle csrf or gzip compression of the response, auth, etc. Telling people to juste use the standard library doesn't help. Of course it is available. But often there is a need for more.


Look, I'm not for a moment suggesting that a proxy application would be a good fit for Django (or even Python). I'm talking about 'building a full stack web application in a reasonable amount of time, with auth, with a database, etc. etc.'


> No one in their right mind would say: just use the standard library but I've seen it online. That discourse is not helping.

I would say that.

The most important thing about standard library is its stability. You won't ever need to touch code that works with standard library. It's finished code. Other than bug fixes, of course.

Third-party libraries is a very different thing.

They gets abandoned all the time, so now you're left with burden. You either need to migrate to another library, maintain that abandoned library or live with huge chunk of code that might be vulnerable.

They gets changed often enough, as their developers probably not so careful about backwards compatibility, compared to core language developers.

Third-party library is a liability. Very rarely its source code is an ideal fit to your application. Often you'll use 10% of the library, and the rest is dead weight at best, vulnerability source at worst. Remember log4shell? Instead of using standard logging code in Java, some developer decides to pull log4j library which is very nice to use, has lots of features. It can even download and execute code behind your back, very featureful.

Of course I'm not advocating to rewrite the world. This is insane. Some problems are just too big to solve by yourself. I also should note, that different ecosystems have different approaches to the language library and overall library culture. JS is terrible, while Go is not that bad, but it's not ideal either.

But my absolutely 100% always approach is to use standard library first and foremost. I won't use third-party library just to save few lines of code or make code more "beautiful". I prefer dependency-free boring repetitive code any day.

And if I'm using third-party library, I'm very picky about its stability and transitive dependencies.

It also depends on kind of company. My experience has always been: you write some service, you throw it at production, it works for the next 20 years. So you want this code to be as self-contained as possible, to reduce "chore" time with dependency management. Perfect application is a dependency-free software which can be upgraded by changing "FROM" line in Dockerfile. It is stable enough that you can trust CI do that.


I don't think that everyone is capable of or should be implementing csrf protection or cors handling. While the standard library is an awesome starting point, telling people that it is sufficient is not going to convince them.


I wrote CORS handling in one project, it's like 10-20 lines of code. Very simple and well documented feature.


Good for you but most people don't even know what a preflight request is so I would maintain my position that it is not obvious.


I mean, I'm keen on a small number of dependencies too, but the smaller the scope of a package you go, I find the more likely they are to be abandoned. The Go JWT library has been forked twice because it became abandoned by the original authors, just to give an example.


In my experience frameworks (in contrast to "libraries") add complexity making your application harder to understand and debug once you get past the initial prototype.

Also, by their very nature they almost require you to write a program of a minimum size even when a simpler program would do to solve your problem.


This has been my experience as well with almost all frameworks.

It goes like this: the framework helps with the initial progress, because framework works with the more typical use cases. This allows you to "prototype" the solution and show progress to potential users etc.

But then you have a specific use case that does not fit the model of the framework, and you will end up going around the limitions of the framework. You often end up spending more time that you saved with the initial implementation.

My experience with core Django is that it has so many hooks and ways to inherit functionality, that it is extremely rare to end up with such problems. But it still means you need to learn when to use what feature, and how to structure your solution. I had to learn this through painful experience. I am still making mistakes, such as the "single-file status page app", a mistake which cost me several hours of productive coding. That might not sound like much, but when working full-time and running several side projects, few productive hours is extremely costly.

Most third party Django apps, even the popular ones, suffer from the framework problem, however. For example, I have have had to rewrite django-ads and django-distill, because their structure was limiting me from implementing features I needed. I just ditched django-formset as well.

I believe the reason for the limitation is that these third party apps have not been exposed to enough use cases and users to overcome the framework problem.


> Also, by their very nature they almost require you to write a program of a minimum size even when a simpler program would do to solve your problem.

I'm not sure I agree, sure they require you to pull in a large dependency, and that might not be good for some use cases (particularly microservices) where you're sensitive to the final size of the image but for e.g. with Django you get spawned a project with settings.py which configures your database, middleware, etc. and urls.py which configures your routes, and then you're really free to structure your models and endpoints however you like.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: