I've seen this problem in a few different contexts now but I'm not sure what it's called or how to think about it.
Suppose I have a service, AccountService, that serves account
s from a database, e.g.
account.id
account.fname
account.lname
account.email
account.business_address
account.tax_id
account.invoiced
- ...and so on.
It is a "platform" service used by many other services, such as PaymentService and PreferenceService. Suppose each of those services for some reason have to GET a list of accounts according to some criteria. For example, PaymentService needs a paginated listing of accounts with the fields business_address
, tax_id
, and invoiced
set; meanwhile PreferenceService needs to send batches of emails to accounts whose email
field has been set. (Somewhat contrived example.)
Now, I can obviously expose 2 endpoints in AccountService such as getAccountsWithValidPaymentDetails() and getAccountsWithValidEmail() that execute corresponding SQL queries. (Or more sophisticated forms of this.)
But it seems then like my AccountService is being tightly coupled to a feature specific to downstream services. That is, why does AccountService need to know what PaymentService considers a "valid" account state for billing? Or another perspective: If PaymentService modifies their definition of a valid accounts to bill, they'd have to modify AccountService—doesn't that seem wrong?
The real scenario I'm dealing with is a little more complex, sometimes joining data from multiple upstream services. And a key aspect that highlighted the problem in all the contexts I've seen is, for some reason, paginated views, i.e. getting 10 items at a time after applying some filter. In layman's terms, it's as if the fact that one must filter at the database level (i.e. in the upstream service) forces a tight coupling between the upstream and downstream service, namely by having to implement a downstream service's concept as a filter in the upstream service.
Is there a name for this problem or related concepts?
Is there a pattern that can avoid this kind of coupling?
If the answer is a technology like GraphQL, etc. then out of curiosity, what was the better approach before those technologies existed?