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

I couldn't disagree with this any harder. I'm a Java BE Engineer who joined a Go shop, so I have a direct comparison. Both are microservice environments for products of similar complexity. It is insane to me how much less productive Go is for your average microservice enterprise environment. I'm sure it's great for systems programming or tool development. I like the simplicity. But the ecosystem is borderline useless for larger scale enterprise-y service landscapes. GRPC and Protobuf are overengineered and underdocumented, a lot of things are seemingly optimized for Google's specific needs.

We are more people, we are more experienced and have a decent engineering culture. Yet we're definitely less productive than the last average, traditional Java Spring Enterprise team I've been in. "Circumventing" a framework restriction (which rarely happens if you stick to good practices) is MUCH less effort than building things yourself from scratch.



You're saying that grpc and protobuf are over engineered but you're happy with Spring?

gRPC and protobuf are just transport and serialization, they have nothing to do with business logic, on the other hand Spring is a heavy, bloated framework.

Most Java frameworks are complicated backed by layers of abstraction and black magic.

btw no framework does not mean you don't use any library, there are some good lib aka micro framework that have everything you need to build modern and decent api servers.

https://github.com/go-chi/chi

https://echo.labstack.com/


> btw no framework does not mean you don't use any library

I hear that silly argument "no framework === rewrite everything from scratch" far too often.

There's a giant difference between libraries and frameworks! It's terminology: it's a framework if you build your app inside it. It's a library if you build it inside your app.

The later is fine. The former: I dislike it - even in JavaScript, Ruby, Rust or anything, I wrote a longer post on that[1], which got a lot of discussion on HN. Most of it too in the line of "lol, I use a framework because I don't want to write it all myself", completely missing the crucial first paragraph in which I carefully tried to explain the difference and explain that re-using code != using a framework.

[1] https://news.ycombinator.com/item?id=33185010


If you don't use a framework, the structure of your code will still grow to resemble one anyway. Something internal, nonstandard, more difficult to maintain, and probably less congruent with the problem space.


That's actually addressed in the article:

> You may feel that building your services without a framework will take ages. Especially if you are coming from other programming languages. I understand that. I had the same feeling a couple of years ago when I started writing in Go. It was an unjustified fear. Not using a framework doesn’t mean that you will need to build everything yourself. There are many proven libraries that provide the functionality you need.


> more difficult to maintain, probably less congruent with the problem space.

This is not true as blanket statement. It may. But with "a framework" you are bound by the architecture, upgrades, use-cases and so on that this framework covers. And limited by the ones it doesn't.

In practice, choosing a framework on day one of the project, means you cement yourself in architectural choices when you still lack all information about what architectures will be needed. You don't know your problem space.

All you know, for certain, is that his problem space will turn out different than what you thought it would be today. Flexibility to move along as this evolges is critical to "maintainability".

In practice, therefore, you'll quite likely end up with a framework that is severely harming your ability to write maintainable and congruent code over time.


That's highly dependent on use case and baseline skill set of a given team.

Often times you can get away with a subset of functionality which makes for a simple implementation.


But for those who do use a framework the problem space and failure modes are quite similar: some succeed at fitting in the unavoidable domain code into the blanks left by the framework, others build a "framework within the framework". And occasionally that might even be the right call, because the framework+blanks fits some of the requirements so well, while others exist that are served well by the "framework within the framework". Does not contradict "most framework within the framework are horrible mistakes" at all.


That’s because your premise is weak. You argue that Django is the wrong choice for lots of projects but the counter factual is that our job is to figure that out. We have to choose the lesser evil.

It’s not convincing to just call everyone stupid. Everything is a trade off. You have no idea what those could be in any particular situation so that’s why your whole argument falls apart

Then you focus on construction and coding and ignore everything else a framework offers, which has downstream effects on coding and construction. It’s not all about the code. The coding is actually the easy part

The only projects ppl pay us is for the ones that are so large and complicated that if you don’t use frameworks, you’re going to either die or go crazy


This reminds me of an debate I was having with another dev who said python was "pointless" and that there was a better, more elegant way to do things.

I asked him what is a better way to quickly/easily stand up microservices/apps for clients (90% of my job), if not Django (or Flask/FastAPI, etc).

His response was "django is great, but it could have been written better and in another language" ... well, sure, great... but that doesn't solve my problem, lol.

We use Django for tons of client projects and rarely ever hit the "limitations" wall. It is mostly CRUD apps, so that helps but I would argue the time saved using frameworks in our shop is much more than the time lost spent on working around limitations. I do think the author has good ideas tho, good principals... but if you know your craft well, you know what will/won't work in a framework and how to solve that.


Yeah, it’s a smart guy with a bad idea. Story of all of us in HN!

There’s always a better way to do things but we live in a fallen world. Some bullshit will always arise to make your life more complicated.

It’s like you said, when you hit whatever limitation, you’ll have to figure out a way around it.


Yep! I just thought it was mostly funny how a "better solution" is claimed and then after looking at the problem that solution only exists in theory, lol.


> It’s not convincing to just call everyone stupid. Everything is a trade off.

I wish it were less acceptable to play the "balanced" person in the middle.

If and when there is a balance point, someplace where the actual truth tends to be, imho, it's almost never in the middle.

There are reasons those frameworks (and Golang, too) tend to do things in an opinionated way.

I wish there were more strong opinions lightly/loosely/weakly/gently/another-word-ly held[1]. I think opinions too strongly held is a surer path to there than starting from a place of trying to "meet in the middle."

[1] DDG-ing the term showed a bunch of adverbs of holding! Here are a some:

    why it works: https://www.nwea.org/blog/2022/strong-opinions-loosely-held-demystifying-social-emotional-learning/

    someone also said something on medium: https://medium.com/@ameet/strong-opinions-weakly-held-a-framework-for-thinking-6530d417e364

    contrarians take a stand, too: https://commoncog.com/strong-opinions-weakly-held-is-bad/


Yeah, there’s a reason for everything. But apparently not to use a framework. Thats “always” a bad idea, apparently.

I’m not trying to meet anyone in the middle. I’m saying use a framework all the time, every time.


You miss a crucial nuance that I did make:

> there will be a lot of projects where Django is a very poor choice.

often and lot is crucial - it's opposed to all. Because it implies exactly what you then continue to state: that its our job to figure out if this project is one of those "lot [..] with a poor fit" or one of the ones where it actually, and will remain, a good fit.


Yeah, look, you waffled this one but I still liked it. I can tell that you know what you’re doing and that you have something to say. I may not agree with it but I didn’t dismiss it.

But when I say premise is weak, it’s a technical term. Doesn’t mean it’s wrong.

I mean, in this case I do think that, but that’s why you’re getting so much pushback. Even if the premise was right, you’d still be getting pushback.

On the next post, remember to spend extra time there. It always comes back to haunt you.

Remember that the reader is smart but in a rush. The less words the better. Keep it country simple.


> You're saying that grpc and protobuf are over engineered but you're happy with Spring?

This was my reaction. Every Spring app I've been involved with was a nightmare of gratuitous complexity that was nearly impossible to debug. I'm sure if I were a master of Spring I could figure it out, but that's the nice thing about Go--pretty much any programmer could work out what's happening even if they aren't particularly familiar with Go. You don't have to trace something from XML to Java, and there is basically no magic (maybe the odd bit of Go reflection is the exception to the rule, but it's much less common than in Java/Spring and the "magic" is much less magical).


You can use yaml nowadays with Spring. It's not anymore that ugly stuff it used to be 10 years ago where you had to wire everything together bit by bit.

I believe one thing that really tells the Java world apart from others is the heavy reliance on DI containers like spring/karaf/osgi etc. Once you understand that, everything is simpler.

I would say "believe me" in a face to face conversation, but even then it's proven useless :)

Working with Spring for me has become one of those things like when people suggest to "choose a boring technology" to build something. Yes, that's it. In the positive sense, of course.

There is literally an easy integration with everything you need, the learning curve is relatively smooth, and yes while it's true there are quite a few annotations you need to get used to, I believe after a few days you finally get used to it, and finally it simplifies a lot your development experience rather than making it worse.

For me the only reasons I would pick Go is because of native binaries (smaller footprint, memory, cpu etc), and it's "slim" for simple programs (like Python, but again binaries/native). I also like a lot Go's syntax so that's another pro.

Finally they are both very solid languages with strong tooling and wide communities.

Ps: the cool "new" guy seems to be Quarkus, though :)


Spring Boot is actually a VERY easy to use framework. So much so that Netflix shifted out of writing their own libraries to using Spring boot.

For example, the code below is a complete Spring Boot application with all of the default configuration in place. It will take just a couple of minutes to have this running and it provides quite a lot of features under the hood - which you don't need to worry about.

@SpringBootApplication @RestController public class DemoApplication {

@GetMapping("/helloworld") public String hello() { return "Hello World!"; } }


I write Spring full time these days. You may have Stockholm at this point (like me), but Spring is terrible in two areas:

- when things go wrong

- onboarding newer / more junior devs

For point 1, there are so many layers of abstraction and 20 page stack traces that you could fill an entire log buffer with just one NPE...

Kidding aside, I can't tell you how many times I've wrestled with the auto-configure magic. The reality is you'll include so many "starters" in a medium use app, you won't know whose including what. A polluted Spring container is a real problem. That isn't the only problem, but it's one of the more prominent. You may say "well write cleaner code!" and I would reply that Spring is conducive to writing code that doesn't fit well with the framework, and that's mostly because you have to understand 10+ years of architecture decisions when you want to do anything beyond the basics (That's why we mostly don't reach for the "Spring" way to do things anymore, just the simplest way). All that is to say, there is a reason Spring development has been supported by Spring consultants.

For point two, It's very easy get started but it's very difficult to mature into a fully productive dev. The things juniors and mids struggle with the most is unpacking autowiring and how to resolve those issues, how to properly handle async behavior (especially with Spring fully embracing WebClient and Reactor now), and database connections.

But yeah, outside of all of that, very easy to use, sure.


> Kidding aside, I can't tell you how many times I've wrestled with the auto-configure magic.

Because everything in Go is explicit you can actually follow a short series of function calls when debugging instead of staring at a 50-function stack trace with a bunch of obscure Aspect4J magic while you feverishly search the Spring JavaDocs for whatever specific error message you're getting.

Go is a dumb language and I like it. Everything's obvious and you can't get too cute. Now that there are generics the only thing that I'm really jonesing for is a decent collections framework in the standard library... generic map, filter, fold, etc. on slices would be a real boon to productivity IMHO.


I'm a competent dev in a dozen languages including Java, I am not a professional Java developer. I've had several instances where I've had to work on a project using Spring and every time it was a freaking nightmare. Not because I am not capable, not because it didn't work, because Spring took everything and shoved it behind 15 layers of abstraction and told me to figure out the magic incantations to get it to do what I wanted. When I tried to figure out how Spring actually worked it was like trying to figure out a whole new language.

My contention is Spring is great for those who have been initiated into it's ways and like to be the members of the Martian priesthood that sing canticles to the Omnissiah, but for those who want to understand what is going on and why Spring is anathema.


is there a go-to third-party documentation for spring (eg a book) you would recommend? I find official docs difficult to navigate. (which are either very narrow tutorial or in reference format, with important details omitted).


https://www.baeldung.com/ has been my lifesaver.

It's usually search "baeldung spring <whatever I am trying to figure out>" and I get a nice article telling me how to do it but also explaining it as well so I can have the knowledge in the future.

I think the main author Eugen (there are many now) has a nice book.


> For example, the code below is a complete Spring Boot application with all of the default configuration in place.

Uh no, you forget the part where you have to add a bunch of stuff to your build system (maven or gradle, usually), so it actually knows what to do with this.

You can't just compile that class with java -c, run it, and have a running application the way you could do it with lighter-weight frameworks.


Yes, you have to learn how to build a minimal pom.xml to make this compile and run. IntelliJ will do this for you with its Spring Boot project template. After that, it really is this easy.

I consider the boilerplate needed to build a main.go file that starts a gRPC listener to be harder.


>So much so that Netflix shifted out of writing their own libraries to using Spring boot.

The irony is that my team shifted from using spring boot to another framework for 'performance reasons'. Each instance only handles ~ 1k tps. Sighs


Did they profile the system to find out where the bottlenecks are? What was their findings? And to which framework did they move?


Writing a single get endpoint that returns string is easy in almost any language/framework today, you didn't really show anything with it. The real pain starts when you have to add database connection, migrations, auth, security and all that.


Twirp (by TwitchTV) is a good gRPC alternative. It’s significantly lighter and easier to use.


Better than an alternative is Connect, which is gRPC but also supports gRPC-Web and the lighter weight Connect protocol (which seems inspired by Twirp) https://buf.build/blog/connect-a-better-grpc I like it because it solves most of my complaints about using gRPC from Go without giving up on gRPC.


GP is extrapolating from their experience and assumes that everyone would feel the same way.

“I’m less productive in Go compared to Java Spring” => “the whole world is less productive in Go compared to Java Spring”.


I use chi for one of my projects and though it was fun implementing everything myself. Having a framework would greatly reduce the length of my handler functions and the chance that I mess something up.

I had to: manually manage sessions and jwt token Implement message flashing

Even reading data from a form was a little too verbose for my liking


I’ll vouch for chi here as well: if I’m building a Go web service and I really need to go one step above http.ServeMux, it’s the only library I consistently reach for.


Spring boot can be about as intrusive as the built in grpc server. This is just an, at best, outdated take.


On one level, it is not an outdated take. There is a LOT of old Java out there: out of date JDKs, out of date versions of frameworks. There is still a lot of Struts 1.1 out there.

I think our industry would look a lot different if more companies were keeping their Java apps up to date.


I have to switch between Java Spring boot, Go and Rust. The latter two are framework less and easy to understand just by reading the code. Spring-boot development requires so much googling to figure out why I get UnsatisfiedDependencyException and what each annotation means. Even if I get it to work I still don't understand how it works.


I'm not sure that's contradicting the parent post.

A framework is an added friction to picking up a development environment but potentially a huge asset to velocity once people are up to speed. You haven't gotten properly up to speed in that framework and that site's use of the framework. Perhaps you never spend enough time in that domain to really need to pick it up, in which case you'll always pay the "WTF is this?" tax.

But it's equally likely that once a person's up to speed in the framework they're efficiency is greatly enhanced.

A programming language isn't just the syntax of the language; there's also knowing the common idioms of the language, understanding the runtime / build environment, knowing when and how to leverage the standard and extended libraries/package ecosystem, etc. Frameworks fall into the "extended package ecosystem" which is vastly different from language to language, and sometimes _within_ a language if the language is sufficiently mature.

Some of it is "just math" and some of it is understanding the culture.


Some of the pains with Spring Boot don't go away even when you understand it better. The fact that the framework relies so heavily on reflection makes debugging a pain, turns what should be compile-time errors into runtime errors (which, among other things, makes updating libraries annoying), and also leads to very slow integration tests. I also haven't yet met a developer who fully understands what @Transactional does, exactly.

I agree Spring Boot brings a lot to the table (Spring Security alone, for example), but at the cost of significant downsides.

I see the benefit for larger and more diverse teams, but personally I would choose lighter-weight frameworks and libraries, even if at the cost of having to do more plumbing myself.


> I also haven't yet met a developer who fully understands what @Transactional does, exactly.

I have found Spring Boot to be a step forwards from the old Java EE world in basically every way except for this. Transactional boundaries are somehow more difficult to analyze.


> The fact that the framework relies so heavily on reflection makes debugging a pain, turns what should be compile-time errors into runtime errors

This perfectly explains my problem with the fx library, and why so many java devs seem to gravitate to it


> You haven't gotten properly up to speed in that framework and that site's use of the framework.

I've been working in Spring framework for years, and don't understand it. I suspect most of the people who develop it don't understand it either, as it's so enormous it's probably impossible for any one human being to really understand it.


I'm not trying to defend this or that development environment or framework, just pointing out that there are trade-offs everywhere.

I don't understand speculative execution or any of the other deep voodoo that happens in modern CPUs that spend enormous amounts of energy presenting the "I'm a PDP-11/70 with way more memory and bigger registers" lie to programmers.

These days I'm not even sure which part of my computer is running the networking stack, or where my computer is located.

We stand on towers of abstractions, and complain about the ones we're forced to notice. I don't think many people understand "it" these days.


I mean, you sound like you try to use a tool without knowing it.. why exactly do we believe that it is okay? Would you expect to be able to use a crane at first try?

Spring boot does put a layer of abstraction over ordinary “linear” code, but it is not black magic, if you understand its DI part, you will basically understand everything (in short, spring is only allowed to generate new code, not modify existing one. So it works its whole “magic” by generating subclasses at runtime. With this requirement in place, most of its working makes clear sense. It has an internal list of available beans, and you can inject them by type only (@Autowired/@Inject) when it is the only bean of said type, or you may have to be more specific by naming the desired bean. And it is a simple graph of such injects.)

And it is a well-understood convention, above all. I can go to another spring shop and expect to see JPA entities annotated the way I’m used to (which is another very powerful feature. Can it be misused? Sure. Does it save a shitton of time, and less code means less bug? Yep. Plus, before the “ORMs considered harmful” people join us, they were always meant for OLTP, not OLAP, and as a mapping to/from db records, where they absolutely shine. Don’t try to OUTER JOIN on a subquery of whatever with them, but feel free to write your SQL and map its results to a business object).


I switch between Go, Spring, and ASP.NET (the latest one, which used to be Core, but isn't anymore). I don't think your Spring experience should be extrapolated to other frameworks — dealing with it is certainly significantly more painful than working with dotnet.

You don't get type safety for your database queries without jumping through hoops (compare anything it provides to LINQ — it's not even in the same league). Hibernate feels like a significant step-down after Entity Framework (I might be an idiot who doesn't know how to use it, that's entirely possible, but this just proves the point — it was easy to get started with EF, it didn't require a doctoral in ORM studies to become proficient with, it's dead easy to write queries for (thanks to LINQ), and the vast majority of those translate to pretty efficient SQL which is fine for 99% of my queries).

You get lots of behavior decided at runtime (while ASP.NET for the most part is very explicit in its configuration).

It also doesn't use many annotations (most of those I use are fully optional, like adding pretty names to database columns; and those can be configured through explicit method calls).

It does require DI (and IoC containers are swappable if you don't like the default), but I didn't have nearly as many issues with it as when working with Spring projects, whatever the reason may be.


From what I remember from spring boot it is (or feels like) more of a system to assemble your application from discrete modules, but which modules are used for what can be determined by configuration and various rules.

I mean the use cases of that will be limited these days; application architectures have changed to the point where what used to be a module within a Spring application can now be a microservice to be enabled or spun up depending on rules defined outside of the application.

But this is a very superficial point of view, I haven't seriously touched Spring for a decade and, thanks to some experience with Go, I feel like I won't need to either for most modern-day applications.

While Go may not be for everyone or for every application, its mindset of keeping things simple, just use the SDK or some libraries, etc does make for better developers. IMO.


This 100%. I think the people largely arguing for no frameworks have no idea what real productivity looks like at large scale engineering orgs. This mostly means you are not handcrafting libraries. There is a dedicated team who manages platform tooling including the frameworks/SDKs you use. Product teams may contribute to that but they will mostly be consumers. I always equate this to car manufacturing. I am not buying a kit car, I am not buying a hobby car, I'm buying a well engineered product from a large scale manufacturer. Frameworks and platforms fall into this category, especially for enterprises.

I think it's fine for small teams not to use frameworks, and maybe 200 person engineering orgs are made up of many small teams who just want to agree on a protocol rather than shared framework/platform but once the scale starts to increase you really need to start tightening up and implementing some better standards.

People constantly talk about not being Google, well let me tell you the people scale is all the same, the amount of legacy infra is all the same. If you haven't peaked into the depths of the messy multi-decade enterprise you have no clue. Your 4 year old company that you joined 6 months ago is no comparison to something with a legacy of 3 decades with 2k+ engineeers scattered across a disparate org trying to modernise in the cloud or whatever comes next.

Full disclosure: I work on https://micro.dev - a framework for Go


“Real productivity at large scale engineering orgs” means a bazillion different things, because a big org can afford to have different teams specialise in different things.

No-framework Go makes the most sense to me, because a big framework doesn’t make sense for all types of project, and the set of projects where I’d reach for a big framework just doesn’t intersect _at all_ with the set of projects where I’d reach for Go.


It goes back to, what is a framework and what qualifies as a big framework here. I think classic rails isn't the fit, but something that's an extension of gRPC definitely works. What gets handcrafted is a lot of layers around gRPC or far more stuff around HTTP.

When I'm working on personal projects, frameworks don't make sense for me. When I'm trying to engineer something at scale e.g https://m3o.com then I need that standardisation at the platform layer, the framework layer, the API layer.


When you're building something "at scale", there'll be business logic API services, cache services, routing/dispatch services, and many other such things.

What I'm saying is that I find business logic-centric API services to be a good fit for larger frameworks that take ownership of more of the low level logic, and I don't find Go to be a good fit for those, at all. Inversely, I find Go to be a much better fit for the more "technical" services (provided we're not at the must-squeeze-every-ounce-of-performance C++/Rust level of requirements), but I also don't want a framework getting in the way.


Pretty much, not using some framework just means you will be re-writing same thing over and over again.

For our small-time ops use we ended up on Gin/Gorm/Zap/Opentelemetry + some code for internal SSO and it works fine but I'm slowly thinking of making a wrapper that preconfigures that setup as there is pretty much same boilerplate repeated between many projects.


I have been a web engineer for a decade. I've worked on Java Spring apps, PHP, Node.js (express), Python (both flask and Django), clojure, Rust, and now Go. I have worked on teams large and small, and on codebases old and new.

In my experience the problem with this kind of conversation is that you can actually have a pleasant experience in all permutations of the above. Since people have a ceiling on the number of projects they have worked on for a long enough time to have a reasonable opinion on the approach, they come out of this with massive biases and cannot accept that others have had pleasant experiences on the same tools and team sizes if they have had an unpleasant one.

I _promise_ you that you can absolutely have a relatively long-standing codebase without a framework that is a dream to work on and has been touched by many engineers in a huge corporate setting. Similarly I could show you absolutely unworkable travesties that have to eventually be rewritten despite being written with frameworks that claim to prevent this kind of thing occurring.


> I _promise_ you that you can absolutely have a relatively long-standing codebase without a framework that is a dream to work on and has been touched by many engineers in a huge corporate setting. Similarly I could show you absolutely unworkable travesties that have to eventually be rewritten despite being written with frameworks that claim to prevent this kind of thing occurring.

Conversely, you can absolutely have a “relatively long-standing codebase” with a framework “that is a dream to work on and has been touched by many engineers in a huge corporate setting.” And I could show you unworkable travesties that have to be eventually rewritten despite being written in library-only microservices that claim (because “micro”) to prevent this kind of thing from occurring.

Whether selection bias from your experience or an appeal to authority, there isn’t much to your argument. To me it just sounds like comparing well managed to poorly managed codebases.

If I have to manage a team, I’d much rather have the framework laying the groundwork for documenting “how we do things” than rolling consistency out ourselves.


> There is a dedicated team who manages platform tooling including the frameworks/SDKs you use.

Ah, so an organization so bloated that you have entire teams "managing platform tooling" (whatever that means) instead of iterating on features customers actually care about.


When you start to scale for your amount of customers and features, you have to manage caching, job queues, and more. Things frameworks like Rails or Django provide mostly OOB. If you’re using Go or Node, you’ll end up writing your own de-facto framework (even if “writing” means pulling in different libraries and gluing them together) around those features, especially in the case of micro services where you’ll want each of those things available in each service.


micro.dev is different from an actual go framework go-micro.dev ?? (https://github.com/go-micro/go-micro)


Yup, I was the author of go-micro. It was very much a standalone Go framework aka common interfaces grouped together for distributed systems development. By using interfaces they effectively became pluggable abstractions for infrastructure. Unfortunately I don't think a Go library alone solves the problems I was trying to solve so it got merged into Micro which is platform that includes a CLI, API, Runtime, etc. It powers https://m3o.com


What if any is the relationship between https://m3o.com/ and https://micro.dev/ ?


We used Micro to build and offer Micro services on M3O. Every API to you see there is powered by the open source equivalent Micro service here https://github.com/micro/services


Different strokes I guess. I've previously worked at big orgs. with Spring, now working with Go microservices and enjoying it by and large.

I don't miss the days where I had to deal with random missing or conflicting beans stopping my app from starting. The nice things about a Go app is because the control flow is so exposed, if it compiles you can be pretty sure it is going to run, and if it doesn't compile you can go to the red in your IDE and fix it.

Adding an endpoint is a matter of updating our OpenAPI file and doing `make oapi-gen` for the code generator we use. I think this is a similar level of effort to doing the same with a mvn or gradle command.

The real difference I notice between Go and Spring microservices though is how much easier it is to dev and debug multiple microservices - it is trivial to compile all of our Go microservices and boot some of them up for debugging without eating all of my laptop's RAM, which is especially relevant if I also want to run them in Kubernetes locally.

I will say I do miss some of the niceties of aspect oriented programming with Spring.


By far my least favourite thing about the Java web ecosystem is how weirdly obscured the bootstrapping process for starting processes is. So much of how your application starts is determined by XML files and DI frameworks that I often have no idea (or am sometimes not even exposed to) where the `main` function is.


I’m only assuming, but I guess your last experience with Java is a bit dated, XML configurations have been largely replaced.

And then what we are left with is a huge, old project vs some new microservice, which would be an unfair comparison in any language


You're totally right. I'm sure things are better now in modern Java and adjacent spheres like Kotlin.


Caring about the main function in a framework-ey app generally makes as much sense as caring about the x86 initial boot code when launching mspaint.exe


Not for newcomers to the codebase. Approaching an application that is forced to make the entire application clear as day (as in Go) is so much easier than such Java codebases because I can just read the code and see what it does. This is just my experience though. The Java codebases are always fine as long as I have read several pages of documentation first, which I've learned to do for those cases.


I've seen devs write caches that were shared between customers because they didn't understand the lifecycle of Spring Autowired dependencies.

Understanding how the framework wires things together is important.


You didn't specify what you meant with "more productive", but if it means "being able to produce more code in less amount of time" then i agree that one can be faster with frameworks/Java.

If you look at the problem more holistically (say "run a reliable service customers want to use") then that metric is just one of many, and more often than not counterproductive vs some other metrics like maintainability and resilience for instance. IME frameworks reflect that and only let you write code fast, or get the hello-world-demo out fast, but neglect the later stages.

I don't know if the conclusion is no framework is better overall, but the frameworks i worked with at least showed mixed results overall.


We're not going to settle this today but I think the later stages are where frameworks shine.

For instance, when Oauth became popular I was maintaining several apps where the original authors had never dreamed of an alternative login method (email and password had been the norm for longer than any of us had worked as developers).

The Rails apps required a few small config changes which I could get from the documentation then HTML for the "Login with Facebook" button.

The framework-less apps were disasters. Each had their own way of doing things. Some used libraries that were no longer maintained, others had rolled their own authentication workflow or half copied the code from another project.

There is a lot to be said for frameworks when facing an unpredictable future. There is a cost to be paid up front as far as learning the framework but the benefits on the back end are enormous.


> The Rails apps required a few small config changes which I could get from the documentation

What Rails configuration would be pertinent to Oauth? Perhaps you mean the application was already using some kind of third-party authentication library (e.g. Devise) that supported Oauth? If that's the case, didn't you just luck out that the developers happened to choose a library that 1. Was still being maintained. 2. Had already added Oauth support?

Most of the Rails apps I have encountered in my career (especially those predating Oauth popularity) used hand-rolled authentication, each different to the next, so it seems that you could have just as easily fell into the same trap you saw elsewhere. It is not clear how Rails saved you here.


When I did Java, I found the Java ecosystem to be very productive because of the libraries available, but Spring was basically useless and was just a way to convert compile-time errors into confusing runtime errors.

Most of the useful stuff in Spring is just thin wrappers over other libraries (including the standard library) anyway.


I expected to see some juicy golang bashing from someone used to sane error handling, pattern matching, and powerful collections libraries. But complaining about "GRPC and Protobuf are overengineered and underdocumented" just doesn't make sense to me.

Those things were basically first implemented in Java. We could argue about subtle differences between Avro and Protobuf but I'm not aware of any credible competitor to gRPC on the JVM in the last 10 years. Thrift and Avro RPC libraries died out years ago, Akka clusters are rather exotic.


Spring works really nice when working on monolithic services, but Golang is on the complete opposite side of the spectrum - Go is really good for microservices.

Spring is more like traditional application development, where you revisit your code multiple time during its long life cycle. In comparison, Golang is more like spit it out fast and forget. Its syntax is so dumb that you can’t possibly misread the code from any angle, so maintenance is also brain dead simple.

In this aspect, using frameworks in Golang simply defeats the point of using the language, because frameworks make codes harder to read. The language is to be used like C, where (almost) everything is manual and explicit.


> In this aspect, using frameworks in Golang simply defeats the point of using the language, because frameworks make codes harder to read. The language is to be used like C, where (almost) everything is manual and explicit.

That's very much a matter of opinion. In my opinion, making every manual and explicit makes it hard to read if you're trying to do anything vaguely high level, because you lose the forest for the trees.


The lack of detailed documentation for grpc is pretty crazy considering how many people seem to be using it.

So many hours wasted investigating fringe http2 characteristics causing odd bugs on the platform.


It is so bad.

Outside of Go (I assume because it seems pretty popular there) the clients for other languages are so hit and miss.

I had to pipe a json into the python client to configure a grpc client (which seems bad) and it took me a while to dig up the correct incantation.

I like the "contract" that GRPC implies but I am not sure I would choose it again.


Try twirp! Same protos for contracts, but everything is much simpler , saner and slimmer , and just uses standard http. It’s great.


I echo what you're saying. What's ironic is that having worked at an employer that heavily uses golang, they ended up inventing their own dependency injection, app framework, web framework, etc. that are outright terrible, and you end up with the long stack traces that some people like to complain about in Spring or other similar frameworks.

So much money was wasted writing and maintaining those frameworks that was so flabbergasting.


Well there are all sorts of programming. Writing code from scratch to solve problems, writing glue code to connect various libraries, fill in the gaps in code generated by framework scaffolding, drag-n-drop blocks in diagrams and code is generated in the background and so on.

Java/SpringBoot/etc micro services developers have certain way of doing things and they are certainly going to hit lot of problems with Go. Since I have worked in typical Java/J2EE/Microservices project all my career, I think, for most devs coming from larger Java ecosystem, mapping their existing understanding to Go way of doing things is pretty much impossible.


That is my thoughts as well.

It sounds like this would lead to more reinventing the wheel than I'd like to see in a product like a web app/service.


Then don't use GRPC and Protobufs. I've had exactly the opposite experience building enterprise software with Go.


There's no word as meaningless as "enterprise-y".

It means literally nothing. A huge company making lots of money has no relation to the quality of its code, processes or tools.

That's not only true for non-tech companies, but even the heavily tech ones whose all products are software.


> GRPC

Assuming this means grpc-go, that's a framework. Perhaps your seemingly negative experience with it actually echoes that the best Go framework is no framework, contrary to your opening position?


This is an insane take lol.

If you don't like GRPC and Proto, use REST. `http.Client{}`, boom make a call.

Go is built for microsevices. It probably has the best std library for web services of any language.


> a Java BE Engineer who joined a Go shop

I didn't need to read the rest of the comment after this.


He could have been working at Netflix, Facebook, or Amazon?


Very little to do with the fact that it's a Java developer. More someone identifying as "x language developer working at y language shop." Most of the time, including this one, it shows that they see x language as a part of their identity. Hard to have objective conversations if that is the case.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

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

Search: