3 ms·
I like the way this pattern trends, but one downside is that it mixes HTTP concerns into the service layer. E.g. the service layer needs to know exactly which
by calebio 3y ago
I like the way this pattern trends, but one downside is that it mixes HTTP concerns into the service layer. E.g. the service layer needs to know exactly which HTTP error code this responds to when returning an error.
If the service layer is used for something other than a web server, e.g. a handler for a queue, we've now got a kinda funky abstraction.
I notice that the HTTP Request and ResponseWriter is also mixed into the service layer, which is another thing I would probably move one step closer to the actual HTTP server and away from the logic that interacts with the database.
In the past I've used `Temporary()` or `Permanent()` along with some other additional fields to help map to HTTP status codes at the HTTP server's handler layer.
- flimzy 3y agoPost author here. For any non-trivial app, there would ideally be a set of domain error types/codes that the various application layers know about, rather than concerning themselves with HTTP statuses. I didn't discuss that in the article, because I felt like it was a bit tangential. Perhaps it was a mistake to omit that detail.
- cpuguy83 3y agoI've done interfaces where centered around the kind of error that happened, which is typically standard across apps and translates well into status codes for http or grpc. Eg "NotFound()" "InvalidParameter()" "Unknown()". That said these could all just be sentinel errors with the normal unwrapping in the stdlib these days.
- lIIllIIllIIllII 3y agoThis is def an anti-pattern. As soon as you have your services suddenly hooked up to something else - chron (or hangfire or whatever) jobs or a message bus - it gets a bit weird because your service layer thinks you're still responding to an HTTP request and whoever works on the service now has to think about HTTP as well which is pretty fucking bizarre to begin with. And your unit tests for a business logic service method are gonna look at HTTP errors? It feels dirty, but not in a fun tap-your-nose way. It's really not hard to just return errors relating to what actually happened (can't find user by id, user is blocked from logging in, whatever) and have the app's ingress points (API controllers, message handlers, job runners) decide how to surface that in a way that makes sense for the specific interface.
- kelnos 3y agoI agree with you in general, and I've never written code in this style. But at the same time, converting between error and result domains is tedious and error-prone. As much as we believe separating concerns is a good thing, it's pretty likely that service layer code will never ever be used outside a HTTP service context, so... so what? I probably still wouldn't design like this in my own stuff, but I'm not convinced it's actually so terrible.
- calebio 3y agoI guess it really depends on what kind of stuff we work on. It's very common for service layers in systems that I work on to be shared between various ingress points (HTTP, GRPC, Kafka handler, etc).