Why not an agnostic sort strategy like filter?


#1

From the 1.0 documentation, regarding fitlering:

JSON API is agnostic about the strategies supported by a server. The filter query parameter can be used as the basis for any number of filtering strategies.

Whereas sorting collection of resources has a strong position about which strategy to use:

The sort order for each sort field MUST be ascending unless it is prefixed with a minus (U+002D HYPHEN-MINUS, “-”), in which case it MUST be descending.

I am wondering why there is such a requirement regarding which strategy to use? While minus sign is nice, they are different ways to represent ascending and descending sorting order.

For example in SQL world we use ASC and DESC respectively. Another example in MongoDB world where we use a key/value hash such as { field: 1 } and { field: -1 }.

Would love to hear the reason behind a strong requirement for the sort strategy whereas the filter strategy let full freedom to the API designer.

Thanks.


#2

We (the editors) want to specify as much stuff as possible, to promote interoperability. Sorting conventions were easy to specify, so we did. Filtering conventions are much more complicated so, while we’d like to specify them, we just haven’t had time to. But that may change. So there’s no principled reason—it’s just been a question of limited time.


#3

Thanks for the quick reply.

Interoperability sounds great. However I can see one issue with the sorting strategy in place.

To give a little context, I’m building an API in Ruby using Grape. Grape allows to specify requires/optionals parameters per endpoints. Using a flat string as the sort strategy was not the best experience so far since:

  • It requires parsing to usable in a database query (though this will likely depends on which ORM you are using). Correct me if I’m wrong, but for example, like I said, MySQL/PGSQL use the ASC and DESC keywords instead of the presence or not of a minus sign.
  • It requires parsing to be able to allow/forbid sorting fields. For example, once could want to allow to sort his resource collection upon email and last_name but not using first_name.

So far I’ve used a hash instead of a string as the sort strategy and I think it works great:

  • sort=email,-last_name becomes {sort: {email: 1, last_name: -1}}
  • Which translate to the following url encoded representation sort[email]=1&sort[last_name]=-1
  • Easier to parse a hash than a string, no pre-processing of the keys to “skip” the minus sign
  • Allows to validate the sort parameter and reject forbidden sort parameters.

I understand that since the JsonApi Format is now in stable state which will not make this change possible no matter what. I just want to open a discussion. I really appreciated the fact that the filter strategy was left to the API designer and maybe the sort strategy should give more freedom as well.

Thoughts?

Thanks for the great work guys.


#4

You’re right that sort=email,-last_name requires a bit of parsing, but not an unreasonable amount in my opinion. Meanwhile, although sort[email]=1&sort[last_name]=-1 seems/is simpler for some cases, I’m not sure it’s really better in general. For example, if we used the sort[field_name] strategy, servers would have to use a library that returns the order in which each query parameter appears (because sort[email]=1&sort[last_name]=-1 and sort[last_name]=1&sort[email]=-1 are different sorts), and that’s a pain.

Right. So, at this point, our only option would be to support the existing format but also add another allowed format (or a format that each API could pick) along side it. Supporting multiple formats would hurt interoperability, though, and I’m not sure the current format is problematic enough to justify adding an alternative.


#5

For example, if we used the sort[field_name] strategy, servers would have to use a library that returns the order in which each query parameter appears

Not sure to understand why. The order the sort fields appear gives you the order to apply them. For example:

sort[email]=1&sort[last_name]=-1 should be applied in order, email ascending first, then last_name descending.

Can you explain a bit more what you have in mind?


#6

Yeah, we’re saying the same thing… The sort parameters have to be applied in order, so whatever tool the server implementor is using to extract the query parameters from the URI has to return those query parameters in a data structure that keeps track of the order…but not all tools will do this, since query parameters are often not order-sensitive.


#7

The URI RFC doesn’t mention ordering at all.

In general, I agree that query params being ordered is not intuitive, as in my few years of experience with URIs I have not run into a single case where ordering has implicitly come into play, but this seems like a perfectly appropriate solution. It’s very similar to the nature of SQL and sequential / synchronous programming.

Japanese on the other hand has lost out… because English is the language of programming. :smile:


#8

Hashes by their nature are unordered sets of keys. Your strategy could either order email,-last_name or -last_name,email depending on how the client handles it. It is pretty syntax, though!