I have just submitted an RFC concerning composable fields (#682). Composable directives are similar: they would allow directives to modify the behaviour of, or prepare the context for, other directives.
Currently, several directives can modify a field, executed in a specific order:
However, we can't establish to execute a directive within another directive, because the syntax @ doesn't support it. Then, this RFC must also involve introducing a new way to define directives, such as using <...>:
In this case, the field is modified by a combination of directive1 and directive2, where directive1 wraps directive2 like this: it first prepares the context for directive2, then executes it, and finally does some clean up work.
How could this be useful? For instance, it can enable to use existing directives to modify the elements of an array, like in this example:
Now, we have a field that resolves to an array of strings, like property tagNames:
We can't directly use directive translate, since it expects a string as input, not an array of strings. We could have this directive also be able to process an array of strings; however, this would go against type safety, and it would not be a long-term solution, because it would not work for yet other inputs (eg: an array of array of strings, a map, etc).
The solution, then, is to have a directive forEach that can iterate through all the elements of the array, and execute the directive translate on each of them. Because directives are composable, it can handle any input (eg: an array of array of strings, or a map) already on the query, without any custom server-side code.
This solution looks a bit hacky to me. Certainly not as simple or elegant as through composable directives.
Also, I don't think that piping can always make it. For instance, if we want to advance a pointer to a specific position in a multi-dimensional array, and only apply the operation on that item... through composable directives, though, it could be very easy to do