|
|
|
|
|
by mungaihaha
257 days ago
|
|
"Here’s a real example: a user signs in with an email and password. That flow touches three services, each with a single responsibility: EmailService::Normalizer strips and downcases the email
UserService::Authenticator checks credentials
SessionService::Creator creates a session" Don't know how to say this without sounding arrogant. WTF? |
|
I get the reaction. For something like a simple login flow, this probably looks like a lot of ceremony. The goal isn’t to over-engineer it, though. Each piece handles a single concern that may evolve independently over time (email normalization, authentication, session creation). Keeping those parts separate makes it easier to test, extend, and reuse.
And while the example is intentionally simple, the benefits show up more clearly in complex scenarios, like when workflows start branching, new auth methods are added, or the same logic needs to run in different contexts (web, API, background job, etc.). Having composable, consistent services keeps that complexity from leaking everywhere else.
It’s not the only way to structure things, but it works well for me.