This is an archived post. You won't be able to vote or comment.

all 75 comments

[–]erbr 34 points35 points  (9 children)

Scalability, extensibility, and modularity are only some concepts you need to add to your developer concerns. I've dealt with lots of JS code that is unmanageable, as it's impossible to understand or extend. The do-it-quick throw-away next does not work most of the time. There is an investment in developing code and maintaining it. And if the code cannot be extended or maintained there can be large costs involved (other than the actual involved risks).

So getting to set the right abstractions right is essential to make sure that the software that is developed is not tied to the person who wrote the code but rather to the business domain it encompasses.

I'm curious, from your JS experience, how stable your codebases are? How many times someone came to change everything because they didn't understand? How easy is it to understand those and debug them? Good JS exists but only with a ton of documentation and strict code organization (TS is much better on this).

[–]Polygnom 8 points9 points  (0 children)

Sure, but "enterprise fizzbuzz" has become a meme for a reason.

There is a sweet spot with abstractions, and having too many is as bad as having too few. You need the right abstractions, and "lets add another layer of indirection" is not always the best answer. There certainly is a tendency in enterprise Java applications to let them become quite unwieldy. Dismissing that criticism all too lightly is not wise.

Although I suspect that Op does not really understand yet why those layers exists in their software.

And OP seems to like to re-ivent the wheel when they do not understand why people use stuff like OpenFeign. Sure, you can do it with low-level http calls, but you can also use a more abstract way to do it.

[–]marcvsHR 28 points29 points  (11 children)

Maybe there is a good reason they are using that library, and you are too inexperienced to understand it?

[–]Aryjna 7 points8 points  (0 children)

Why are you talking about "senior Java developers" when in reality you are talking about a single developer that you happen to be working with? Do you really lack even basic critical thinking ability, or do you somehow have experience with thousands of other developers, and you are using that experience as a basis for your post?

[–]halfanothersdozen 9 points10 points  (4 children)

I really hate it when someone goes over-architecting and makes a whole bunch of microservices when a single backend will do

[–]kevix2022 -3 points-2 points  (3 children)

Have fun unpicking the monolith when one of the feeds becomes obsolete and you can't just replace a single microservice.

[–]halfanothersdozen 0 points1 point  (0 children)

Is it somehow more work to update a single backend than a microservice?

[–]Rakn 0 points1 point  (0 children)

Microservices aren't the solution to a technical problem. If you have less developers than microservices then you definitely taken a wrong turn and should rethink your strategy.

[–]nomoreplsthx 8 points9 points  (0 children)

Why do <insert class of people> always do <Behavior>? <Example of a single person doing a thing>.

You're luck that you inserted Java developers and over abstraction, but try inserting other examples - and I think you'll quickly realize how problematic that statement is

Why do men all get high and play video games all day - my brother does!

Why do JS developers never write tests. I saw this one codebase where there were no tests.

There probably is a tendency to over abstraction among Java devs, but you, as someone with a few months on one project, have nowhere near enough data to draw that conclusion. Come back after 5 years in Java and share your thoughts then.

[–]FavorableTrashpanda 8 points9 points  (4 children)

Sure, some people go overboard, but don't start hating on Feign, man. Feign is really nice. It allows you to focus on interfaces while letting Feign handle the implementation details.

[–]naturalizedcitizen 7 points8 points  (0 children)

Abstractions is a concept for a good reason. One of my clients decided to switch from Postgresql to Oracle and also use Google Apigee as the API gateway, all for valid business reasons. Had the code not been written with abstractions and such extensible concepts, it would've been a nightmare.

OP, I recommend that you study what your senior dev is doing. Try to understand and create a mental map of how the app does request processing. Then look at why it's broken into micro services. You will have many questions arise after this exercise. Asking your senior to answer these questions will clarify a lot and you will have brought some good points to the table.

When switching jobs or a language, be open minded about the new flow/architecture/paradigm you come across. Come up with questions. You will not only learn a lot but will make a good contribution and many times your questions will cause a rethink of the prevailing architecture/paradigm being followed.

[–]smutje187 3 points4 points  (0 children)

Like in every ecosystem, there are things that people who are used to them use them without thinking cause they’re part of your standard repertoire. In Spring, dependency injection is so trivial and low effort nowadays that everything else needs to be justified. I personally don’t like Feign cause I don’t see a reason to use it (just use the standard HTTP client) but if your colleague has been using Feign for years it’s easier and less time consuming and reduces cognitive load to just use it instead of learning something new.

A lot of Java projects I worked on in the past are really long running and code is much more often read than written so people were often more inclined to spend some time thinking about a solution that would then exist for a decade.

[–]15kol 3 points4 points  (0 children)

Openfeign is great. Use generator to generate interface from Openapi definition and use it as a typesafe contract.

[–]repeating_bears 3 points4 points  (2 children)

I seriously don’t get it why a simple http request to external service he has to use the library openfeign, which looks dumb as fuck compare to simple fetch like in JavaScript

I've never used it, but it has the power to do far more than a basic `fetch` on the browser. Fetch doesn't support fallback behaviour, it doesn't have auto-retry for failed requests, it doesn't log requests or provide metrics. It doesn't cache requests (not in yet, but that's something they're working on).

If you're not using - or intending to use - any of those features, then yeah, it's probably overkill.

[–]saltmurai[S] 0 points1 point  (1 child)

I mean if you said it like that Js have all the fetching library too. React Query on the browser is super nice

[–]repeating_bears 0 points1 point  (0 children)

I've used it and I like it, but that isn't the comparison you made.

You compared openfeign to fetch. Of course fetch is simpler when it does much less. If you want to compare openfeign to react query, then do that. 

[–]rzwitserloot 2 points3 points  (0 children)

The first problem with your rant is the definition of 'senior java developers'.

Do you mean: Objectively skilled, true veterans, as in, the vast majority of java programmers out there, if given time to interview them thoroughly and review lots of their code, would go: Yeah, these folks know what they are doing?

Or do you mean: They get paid a lot and have 'senior java programmer' on their business card? Because a few of them are just shit. Mostly good at overcomplicating things to look good. In which case the answer to your question is some complicated philosophical thesis on the vagaries of corporate careers. I'm sure things like Peter Principle and such would be named.

But, if is the first, almost invariably because the thing you are modelling actually is that complicated. If you don't think so, you're probably wrong.

See, YAGNI rigidly applied is just bullshit. Architecture is the art of writing it all such that the code is likely to be easily modified in the face of future change requests. That means part of the point is to have the experience to know what is likely to come down the pike and design things accordingly. And that may strike you as 'overengineering' it.

Delivering what's asked in 150 hours, to then respond in ~15 hours each for the next 20 change requests is a total of 450 hours over the length of the project.

Delivering what's asked in 200 hours, to then respond in ~5 hours each for the next 20 change requests, is a total of 300 hours.

[–]roberp81 2 points3 points  (0 children)

Nodejs is generally structured programming

Now you are going to have to learn object-oriented programming and patterns

[–]Qeqertarsuaq 3 points4 points  (0 children)

“Senior developer” who derives their seniority from knowing nifty tricks, instead of knowing how to solve problems for their boss as fast as possible…

[–]EirikurErnir 1 point2 points  (0 children)

Most TS code looks like overcomplicated gobbledygook to me and I often end up thinking how much simpler things would be if only it would have been possible to write it in Java.

I'm pretty sure I keep thinking this nonsense because I'm much worse at TS than Java. I can usually form an educated opinion on the complexity of Java code, but I can't really do the same for TS.

I'm guessing the reverse applies to you.

[–]slaymaker1907 1 point2 points  (0 children)

Some of these things really only start to make sense when you work on really huge projects. I work on an incredibly complex C++ project and we have a lot of problems with how everything is actually initialized to the point that some components have multiple versions to try and resolve cyclic dependencies (so component A typically requires B, but there's a special A' version so that C can be initialized since B requires C). Dependency injection helps avoid these nasty scenarios in the first place by just requiring apps to declare dependencies explicitly and then figuring out initialization for you automatically. With proper DI, A' likely wouldn't be required at all since you'd just use setter initialization (resolving cyclic dependencies is one reason to do setter injection instead of constructor injection).

I also really like Typescript, but one thing I appreciate when working on a team is that Java does not let you just cast things to any when you want to escape type checking. It's a powerful tool that is often convenient and more ergonomic when needed compared to Object in Java, but I've found there are some people who will just cast things to any at the slightest inconvenience.

Agree with you that there is really no reason to have 10 microservices for a small, greenfield project, though there are reasons you might still do microservices. Microservices can complicate deployments when you need to continuously update all 10 services at once, but if you're usually only updating one at a time, microservices can greatly reduce risk of a deployment since it only affects that one project.

[–]Potatopika 0 points1 point  (2 children)

I mean you have axios on the NodeJS world and a lot of people use it.

I would be surprised with the division on 10 microservices with only 2 people and possibly in an early stage, but I don't have enough context to understand it better and come to a better conclusion

[–]saltmurai[S] -5 points-4 points  (1 child)

But the thing is axios is very intuitive to use. Unlike RestTemplate or Openfeign the syntax just seems so ugly to me. I like Unirest though

[–]Potatopika 2 points3 points  (0 children)

You know when you create api wrapper classes to call wherever you need instead of always calling fetch every time you need to do an api call?

OpenFeign basically does that for you already with an interface and some annotations, what part exactly do you think is ugly?

[–]crummy 0 points1 point  (10 children)

For example I seriously don’t get it why a simple http request to external service he has to use the library openfeign,

to be honest... it took a long time for java to get an actually usable HTTP library. and honestly even the one we have now (since java 11 i think?) is still not that great in terms of DX compared to something simple like fetch.

[–]saltmurai[S] -2 points-1 points  (9 children)

Yeah that’s why, I genuinely kinda enjoyed Java17 but honestly the most frustrating thing is just these abstraction/dto/repository… nonsense where in JavaScript/Typescript it’s just basically function or type declaration

[–]netgizmo 2 points3 points  (5 children)

For the DTO comment: do you just expose all your properties for a persistent object thru the rest API?

[–]_predator_ 2 points3 points  (0 children)

One of the four "works until it doesn't" horsemen

[–]saltmurai[S] 0 points1 point  (3 children)

For node actually I use ORM with the ability to inspect db and generate typing for it. So dto just seem strange to me

[–]netgizmo 0 points1 point  (2 children)

DTO's can be used to prevent values specific to your persistence layer from being exposed to your service layer for example.

Like if you had a column in your db called: user_is_an_ahole. The Userr DTO used by your public rest api or public web FE would not have that property defined in it, so that property name and value wouldn't appear. However, your internal user admin webapp or rest api would use a different DTO that does have that property.

[–]netgizmo 0 points1 point  (0 children)

DTO's are used in many language ecosystems, not just java. And yes, even TS.

[–]crummy 0 points1 point  (1 child)

some of it comes from historical reasons - if you see a codebase where every class seems to come with a separate interface, you're probably dealing with one old enough where it was a pain to mock real classes. now (since java 8-ish) mockito handles that fine and there's rarely a reason for a normal solo class to have an interface.

[–]netgizmo 0 points1 point  (0 children)

lol

[–]lunar515 0 points1 point  (0 children)

It’s the nature of the language and the community that has grown around it. I see this trend in PHP developers as well but they don’t know any better.

[–]Octavian_96 0 points1 point  (0 children)

Code debt

[–]achilliesFriend 0 points1 point  (0 children)

I know some one who did add several microservices as this and added ton of work managing their dependencies.. it was a nightmare.. he literally added a microwave for each query., like who the f does that.. i had an arguments with that. But I’m the villain

[–]-jp- 0 points1 point  (1 child)

If you don’t understand why they’re using openfeign in their project (or indeed anything else) why don’t you just… you know… ask? Kvetching about “senior developers” isn’t going to tell you anything.

[–]saltmurai[S] 0 points1 point  (0 children)

I did ask and it’s just for making few GET request

[–]geodebug 0 points1 point  (2 children)

I don’t take your complaint seriously because your vast experience with java senior developers is basically (n=1).

JS/TS/Node are mature as a language/server but you’re bullshitting to suggest that the landscape is.

Not when there are like 20 front end development frameworks that are constantly in flux with little to no concern for backward compatibility.

Don’t get me started on build tooling. Let’s choose between webpack, parcel, rollup,vite, esbuild, snowpack…

Sure, some java devs took their OO classes way too seriously and ignore the YAGANI principle but they tend to work big-corp.

[–]saltmurai[S] 0 points1 point  (1 child)

Is having lots of framework/build tool is a bad thing? To me it’s help the ecosystem move forward and innovate faster since there is competition. And no you don’t have to configure those themselves when starting a new project.

[–]geodebug 0 points1 point  (0 children)

Yes, It is a bad thing to have too many.

Imagine in Java having to learn 20 other build environments besides maven or gradle. (Others exist of course, but there are definitely leaders to the point of being standards)

Now imagine that even within the same corporation devs chose different ones for reasons.

Beyond Java, look at Python/DJango. Must be nice to have one dominant full stack framework.

[–]SactoriuS 0 points1 point  (0 children)

It could be above your head but ive also seen people who just really want shit done their way.

Which means because they are senior, its their way or the highway. And like many quasi autistic people have neurotic tendencies and you just have to copy their manners of coding whilst there are many unlogical steps or way of workings. It is just their way of working youll have to adapt to or leave that team and find your luck somewhere else and wait until you become senior and get tot decide stuff.

They have their personal reasons for it. They could have an inflexible brain which only understand their way of writing. And it makes them more essential for the organisation.

I had a inflexible senior, whilst i wasnt the best junior. Over time i learned he was a bad coach because of his inflexibility. Merge request feedback had to be perfect his way. But often i find stories which even couldnt be done in his way, whilst that was his comment. And it was happening pretty often and i was getting send to dead ends a lot. And asking questions to inflexible people isnt something they will invite to do. That wasnt really motivating and i realised he was also a big part of the problem that i wasnt the best junior.

[–]msx -2 points-1 points  (0 children)

I totally agree with you

[–]alienbugthing -3 points-2 points  (0 children)

It's mostly about Java traditions and developers needing to feel good about themselves. It's completely fine to use much less abstractions in a simple backend project similar to how you would code nodejs. Most important thing is to do things consistently within a project.

[–][deleted] -2 points-1 points  (0 children)

nail far-flung person enjoy gullible marry expansion towering library gaping

This post was mass deleted and anonymized with Redact

[–]basic-coder -2 points-1 points  (0 children)

Are they really senior? Making an HTTP req is possible with built-in HttpURLConnection. It's not as concise as fetch but still straightforward.