I think this is a really nice pattern, and might use it (in other contexts than building queries).
I am just a little worried that we do not really have an API here that is easy to document and use. The same goes for TokenOperator actually, as I can add any keyword atoms (as you said, use the words that make sense for your app). This means that we then must rely on conventions (otherwise one dev can use
:preload and another dev can use
:include for preloading). I’m not sure this is a necessarily a bad thing; I guess it is as it can lead to bugs easier. With an Ecto wrapper like QueryBuilder, there is no need to document all the keywords for every function or rely on agreed conventions between devs, because they are always the same limited set of keyword atoms. Of course it’s limited to building Ecto queries.
In this specific example quoted above, all these function names contain the word “project”; so in this case it’s easy to find the functions “compatible” for
list_projects/1; we do not even need to rely on conventions or heavy documentation here as the query function names are self explanatory. Actually would be nice to think about other contexts/examples than query building because we have only one context we base our discussion on
In any case I prefer convention on function names shown in your alternative method than the keywords that need to be agreed on and documented in TokenOperator.