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.
> 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.
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.
> 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.
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.
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/
> 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).
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.
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.
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.
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.
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.
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/