3 ms·
Hmmmmm. Mixed feelings about this. “Oh our http handler knows about the db” Ok? Its job here is more or less “be a conduit to the db with some extra logic”.
by FridgeSeal 2y ago
Hmmmmm.
Mixed feelings about this.
“Oh our http handler knows about the db”
Ok? Its job here is more or less “be a conduit to the db with some extra logic”.
It “knows about a lot of things” but it’s also exceedingly clear what’s going on.
The main function is fine. I’ll take a “fat” main function over something that obscures what it’s actually doing behind a dozen layers of “abstraction”. Nothing like trying to isolate a component when you’re fighting an outage and nobody can figure out which of the 16 abstract-adapters or service-abstracted launched the misbehaving task.
The original code might be “messy” but it’s at least _obvious_ what it’s doing, and it can pretty clearly be pulled apart into separate logic and IO components when we need to.
This all just feels a bit…over engineered, to say nothing of the insulting tone towards the other learning resource.
- FridgeSeal 2y ago> Hard-coding your handler to manage SQL transactions will come back to bite you if you switch to Mongo I uuuhh, I hate to tell you this, but uh, if you’re swapping Postgres to Mongo, and you think that hardcoded queries are going to be your migration pain points, I have some bad news for you. The difference in semantics (for any such change, not just db) will bite you first, and wil bite a lot harder. This idea of “we can abstract over everything and then swap them out at our leisure” works less than we’d all like to imagine it does, and crucially building everything to accommodate this utopia, will leave you with mountains of code that will do nothing other than make your teammates hate you and obscure your actual logic. > AuthorRepository Oh hello C#. So instead of cursing everyone who has the misfortune of working on your C#-flavoured-rust codebase of having to write literal pages of boilerplate to inevitably add a new struct/type to the codebase, I suggest leaning into idiomatic Rust a bit more. Personally, I’d make read/delete/upset traits, whose methods take a handle to a connection pool. Logic for sql then lives inside these implementations, and can be brought into scope only when necessary. Something like `my_struct.upsert(&conn).await?`. We have locality of behaviour, we’ve separated IO details out, we have all the same advantages with about 50% less code-noise.
- neonsunset 2y agoDid you mean Java-flavoured? In C#, EF Core already implements a repository with the way its API is structured so most of the time writing another one on top of it is an anti-pattern.
- ph4te 2y agoI don't think this needs to be an all-or-nothing thing, and aside from a few items, it seems pretty standard. We start off with the Zero to Prod model, and when handlers become too large, move them over to "Repository" types. GET usually stays in the handler, vs POSTing a new request for an action that may include several DB calls, channels, async tasks etc.. goes into a "Service" type crate. Its usually little work though. As far as separating "entities" from requests/responses, that seems to be the norm in any language/framework. You don't want secrets to be responded when you create something, or all of your internal properties. When there starts to be too many config knobs, things are extracted to their respective places. I like that this lays out out a framework for it. It doesn't necessarily mean I would start there.