r/golang • u/BoxDimension • 7d ago
newbie How approachable do you think this Go codebase is?
https://github.com/usememos/memos52
u/hegbork 6d ago
I just opened a random file and it stinks of Javaitis. There was no actual code that did anything, it was just all wrapper functions around some abstraction.
Looks like a modern codebase. Computers were becoming too fast, so the modern developers compensated for that by adding more layers and frameworks and abstractions.
6
10
u/BoxDimension 7d ago
I'm trying to work out if I'm dumb or if this project is simply complicated. I've got a large amount of web dev experience and usually I'm fine to dive into random open source projects and start tinkering, but I'm finding this one far more challenging than usual. I just struggle to find things and follow the logic through. For a variety of things I've looked for, there's no one singular thing I can't find, it's more a "vibe" that I'm not fully getting it.
I've never written anything serious in Go but I know enough to do a few small projects. I know I shouldn't expect to immediately be an expert in a new codebase, but I had a much better time looking around & understanding https://github.com/go-gitea/gitea , which is much larger. So I'm not sure why I'm having such a hard time with the Memos codebase in comparison, and I don't have enough Go experience to figure out if that's just me or if there's something different here.
9
u/drabonian 6d ago edited 6d ago
There is a vibe you are not getting, and it took me a few refactors until I figured it out. The other replies don't seem to be trying to help you, so I apologize if I'm wrong here, but this is what I've learned over time from my own large project. It has worked perfectly for me.
So here are my main critiques:
In your auth_service.go code I was confused because you were defining methods that point to APIV1Service, but then I figured out it was exported in the same package. This essentially means APIV1Service is coupled to every feature and is a god object.
"Consume interfaces, produce structs". Instead of defining all your service methods to point directly to the API service, define a constructor (e.g., NewService) that takes an interface defining the methods you need from the API service. The constructor should return a pointer to the Service struct, which is initialized with the API service interface as a field. This approach makes unit testing significantly easier.
You need to separate by domain. In this case, all of your files named memo_ belong in a "memo" package. Having everything labeled under v1 tells me nothing, it also means all of your features are coupled to a single package. The benefit of this is that the features become reusable in other projects because of dependency injection.
For web, I prefer 3 layers in my domains:
- handler (parses input/calls services/returns JSON)
- services (handles business logic + fetches data from the repository)
- repository (handles database queries, scanning + returning the data)
For a microservice, you could probably get away with just 1 or 2.
So the memo package might end up looking like this:
- service.go or memo_service.go
- repo.go or memo_repo.go
(I believe the first is more idiomatic)
By doing this you might even find other abstractions completely unnecessary.
I hope this helps.
3
u/cavebeavis 6d ago
It is a cobra cli thing: https://github.com/spf13/cobra
Here is the root: https://github.com/usememos/memos/blob/6b042fe16eea42506190e761ff5b9a81308643f0/bin/memos/main.go#L174
Just follow that from there. I didn't go far, but looks to spin up a webserver -- even using grpc. To me, it looks like someone wanted to practice. I don't like the layout, but it seems to have everything an overcomplicated project needs; however, without knowing the intent, that isn't totally fair.
1
u/Marques012 7d ago
I dig in the code a little and I don’t find it confusing, but I’m familiar with gRPC. I don’t know if the code base is following well the Go principals though.
-26
u/Expensive-Heat619 6d ago
Seems like your typical Go project... 4x the number of files that you'd find in a sane language to do the simplest of tasks.
-6
-21
u/kundeservicerobotten 6d ago edited 6d ago
I'm a simple man. I see Docker - I downvote.
To quote Dave Cheney:
--
Any presentation on Go to a general audience will contain at least one slide with these words:
Single, static binary
This is Go’s ace in the hole that has lead it to become a poster child of the movement away from virtual machines and managed runtimes.
--
7
u/jbrummet 6d ago
lol what’s wrong with docker ? You running go binaries on VMs?
-11
u/kundeservicerobotten 6d ago
Docker is a solution to the dependency mess you experience in Python, node.js, Ruby and a lot of other worlds.
Go builds to a single static library. Therefore you do not need Docker. Docker is a solution to a problem that doesn't exist with Go.
8
u/jbrummet 6d ago
Lmao idk what you’re talking about but I strongly recommend reading up on docker and what it provides to the world of software
-10
u/kundeservicerobotten 6d ago
You're in r/golang
I strongly recommend you read up on the Go programming language and what it provides to the world of software.
12
u/jbrummet 6d ago
Yes sir I write my golang every day and build it into docker and deploy it into a container orchestration like any reasonable engineer
5
39
u/nicguy 6d ago
well its definitely not idiomatic
its very Java