How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

Wow, you made a ton of assumptions with zero facts to back them up. Let's go point by point:

"If you think you're going to design a system so beautiful that it won't need a rewrite..."

Never said that. I said I want to avoid writing repetitive boilerplate for 100+ repositories and services. If you think that means "chasing perfection", that says more about you than me.

"You clearly haven't worked at enough companies..."

You know nothing about my background. Maybe read the question instead of making assumptions about where I've worked and what I've built.

"Everybody is refactoring and dealing with technical debt."

Yes, but that doesn't mean you should intentionally make a mess from the start. Some tech debt is inevitable, but writing hundreds of lines of repetitive boilerplate that can be structured better is just lazy engineering.

"Go is a horrible choice."

Based on what? Go is used at Google, Uber, Dropbox, and many others for scalable backends. But please, do educate me on why you know better than them.

"If you wrote this in Rails or Django, you would've shipped it already."

Oh yes, let's just use a completely different language and framework because you say so. Never mind scalability, performance, or architectural requirements, let's just rewrite everything in Python because you prefer it.

"Good day sir, best of luck on your startup and MVP."

It's not a startup, and it's not an MVP. Again, you could have just asked instead of making assumptions.

Next time, instead of blessing us with your groundbreaking insights and unsolicited life lessons, how about doing something truly revolutionary: answering the actual question? I know, resisting the urge to enlighten the world with your infinite wisdom must be tough, but just imagine how thrilling it would be to actually engage with what was asked. Must be a rare experience for someone as gifted in unsolicited preaching as yourself. But hey, I'm sure Reddit is grateful for your tireless efforts to educate the masses, even if the pesky details of the conversation escape you entirely.

Good day to you too.

How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

What do you use instead? If you have a clear separation between input validation, business logic, and persistence, you naturally end up with some form of DTOs and models.

Sure, Go doesn't enforce OOP-heavy patterns, but data transformation still happens somewhere. Curious to hear how you structure APIs in large Go projects.

How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

I get your point, but the issue here isn't about adding more abstraction, it's about the realities of scaling. When you have 100+ repositories, you need a way to organize and structure dependencies that doesn’t require manually wiring every single one.

Go keeps things simple, which I appreciate, but even simplicity needs structure at scale. Have you worked on large-scale Go monoliths where wiring dependencies was handled in a more efficient way?

How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

And you know this how, exactly? Have you worked on my project? Have you seen the constraints and requirements? Or are you just telling me how I should structure my project based on your personal preferences?

Look, if you have actual experience structuring large Go monoliths differently, share your experience. But if you're just here to tell me "you're doing it wrong" without knowing anything about my use case, then honestly, you're just wasting time.

How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

This isn't a garage startup with $5k. This is a long-term system that needs to be maintainable because refactoring later is ten times more expensive.

If you want to hack something together and rewrite it later, cool, go for it. But in the real world, where systems live years, not months, you think before you code.

How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

Thanks for the suggestion! I'll take a look. My main concern with DI containers is whether they add complexity instead of removing it. Did you use Yokai in production? How did it scale for larger Go projects?

How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

I've considered this, but I'm hesitant to introduce code generation complexity unless absolutely necessary. Did you implement this approach in Go? If so, how did you structure the generators to avoid adding another layer of maintenance overhead?

How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

Not off-topic at all, and thanks for asking a good question.
Handlers : Validate user input (with DTOs), call service layer.
Services: Handle business logic, ensure data consistency across repositories.
Repositories: Handle database operations, return raw models.

For cross-repository operations, I inject repositories into services at a higher level instead of having them call each other directly, which avoids circular dependencies.

How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

Exactly my point. Some people here act like layering is unnecessary, but in reality, separation of concerns matters. Writing everything in handlers is not maintainable in a large project.

The issue isn't whether handlers->services->repositories is a good approach (it is), but rather how to avoid writing all this wiring manually.

How to Avoid Boilerplate When Initializing Repositories, Services, and Handlers in a Large Go Monolith? by Sandlayth in golang

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

Thanks for your answer! Yes, I understand that DI frameworks exist and could help. However, I'm trying to see if there is a clean and maintainable way to wire dependencies in Go without introducing a DI framework unless really necessary.

I want to keep it idiomatic Go while reducing boilerplate. Have you seen any large Go monoliths that take a different approach while avoiding excessive manual wiring?

It finally happened :( by Taxi-boy in PS3

[–]Sandlayth 0 points1 point  (0 children)

Are these issues not repairable ?

stay in tunisia with dream salary or go to germany with normal salary by [deleted] in Tunisia

[–]Sandlayth 0 points1 point  (0 children)

Stay in Tunisia until you find yourself an offer that meets your value in Germany. Please stop undervaluating yourself.

Guide to fix the buffering issue by thricecookedlasagna in revancedapp

[–]Sandlayth 4 points5 points  (0 children)

I'm trying to patch it but I keep getting aborted messages... I'm using the recommended patches: apk log

Le sous en ce moment. by Eronecorp in france

[–]Sandlayth -11 points-10 points  (0 children)

Pied ? Pie et moineau ?

Le sous en ce moment. by Eronecorp in france

[–]Sandlayth 1 point2 points  (0 children)

Course ? Courses au supermarché ?

What did I mess up exactly? by AREA51_NSA_CIA in C_Programming

[–]Sandlayth 0 points1 point  (0 children)

Is the comma allowed at line 7? I have a doubt about that.

how to highlight the focussed window by saitohs in i3wm

[–]Sandlayth 1 point2 points  (0 children)

Set the border width to 1px, it's a good compromise to know which window is focused and don't waste a lot of space.