Hey @mmport80,
This is a good question. Some of it comes down to how you want to model in the input. I think for situations like this, you probably don’t want to do an input object the way you are now.
The reason is that it implies you could do orderBy: {name: DESC, age: ASC}. The issue is, which column will be used to sort the collection first? Age or name? GraphQL input objects are unordered just like Elixir maps, name is not “before” age.
This points us in a direction of looking at a list, although then the next question of course is what do we want a list of? Doing a list of the current thing won’t help much cause you could still do orderBy: [{name: DESC, age: ASC}]. So instead let’s look at another approach:
orderBy: [{direction: DESC, value: NAME}, {direction: ASC, value: AGE}]
This lets you be a lot stricter about the types:
# on the field
arg :order_by, list_of(:user_order)
input_object :user_sort_order do
field :direction, non_null(:sort_order_direction)
field :column, non_null(:sortable_user_column)
end
enum :sort_order_direction, values: [:asc, :desc]
enum :sortable_user_column do
value :name, as: :name
value :age, as: :age
end
Now, for sure there’s some degree of duplication here in that you’ve got a variety of fields defined on your user type that you’ll also need to add to your :sortable_user_column enum. At the present moment there isn’t much of a good way around this without doing some pretty hacky stuff.
I’m not entirely convinced though that you want it to be dynamic. I think there’s value to having the explicit list of what can be sorted by, because pretty quickly in a lot of apps this won’t be everything.