-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handling ordering and filtering in connections #20
Comments
Ordering with an enum argument seems right. An array of enums sounds good too if it makes sense for your data. The connection model is primarily for pagination. If you don't need it, you can get away with just using a list. Otherwise, you will likely need to find a way to embed data into the cursor to help you request the next set of data. One solution for an append only list would be to simply have the item index as the cursor. Then you know what to fetch from the API by taking the cursor + how the requests are paginated. I think most well designed APIs that support pagination will also provide some kind of opaque cursor that you can also use directly. Keep in mind that it's also not required to support both forward and backward paging. I think most APIs only support forward anyway, which would restrict what you're able to expose through GraphQL. |
Yep, I would add a new argument (we use I would definitely recommend using a list instead of a singular, because in the case where you only have one thing to friends(orderBy:AGE)
friends(orderBy:[AGE]) In fact, the decision to make list coercion work this way was made specifically to enable that kind of
How you'd do pagination definitely varies depending on the backend; that approach seems reasonable to me. In general, I would figure out what data you would need to fetch the next page, and then throw all of that into the cursor (we base64 cursors at Facebook to make it more clear that they are opaque, then the server just unbase64s them and uses the data to get the next page.
👍 |
Thank you all very much! For me this is clear now. To sum it up for new readers:
Example connection field args setting:
|
How about descending order? What's the consensus/best practice? Maybe create another enum for ASC/DESC?
Is it possible then to make
? |
We actually rarely run into this case at FB, and when we do we just define another ordering, so I don't necessarily have a suggestion based on experience here. Your suggestion seems good, though; specifically, I would have input Ordering {
sort: Sort!
direction: Direction! = ASC
}
enum Sort { AGE, POSTCOUNT }
enum Direction { ASC, DESC } seems right to me. You'd then do: {
friends(orderBy: [{sort: AGE}, {sort: POSTCOUNT, direction: DESC}])
} |
@dschafer Is it intentional that the coercion above is not applied to variables? While the shorthand above is convenient when working with literals, it's a bit odd that the equivalent doesn't work when using variables – e.g. one can't use a |
Hm, interesting; you can't use a Facebook internal Graphiql(n.b. query Test(
$name:String!
$sort:[FriendsOrdering]
) {
username(username:$name) {
... on User {
friends(orderby:$sort first:2) {
nodes {
name
}
}
}
}
} with variables {
"name": "dschafer",
"sort": "name"
} yields {
"data": {
"username": {
"friends": {
"nodes": [
{
"name": "Aaron G"
},
{
"name": "Aaron R"
}
]
}
}
}
} Github Graphiqlquery($ids:[ID!]!) {
nodes(ids:$ids) {
id
}
} with {
"id": "MDQ6VXNlcjI3NjAwMDU="
} yields {
"data": {
"nodes": [
{
"id": "MDQ6VXNlcjI3NjAwMDU="
}
]
}
} (this also demonstrates another use of this: if you have a root field that takes a list of IDs in, you can use it for the single ID case as well (though of course the response will still be an array). |
Yup – my assertion here is that, for convenience and flexibility, it should be permissible to do This also gives an easier migration path to move these things from scalars to lists. |
BTW, the behavior as above for values is actually defined by the spec in http://facebook.github.io/graphql/June2018/#sec-Type-System.List. I just posted an RFC to make the same allowance for variable types. I believe this adds a nice symmetry. graphql/graphql-spec#509 |
The need come from displaying the user a list of nodes that she should be able to sort/filter.
I'd like to get a better grasp on the philosophy behind
Connection
s and how would one go in building a backend to support the{before,after,first,last}
pagination along with ordering/filtering.From graphql/graphql-spec#4 I understand that GraphQL per se doesn't really care on how you handle pagination/filtering/ordering. Hence I'm writing here even if I realize that this is not strictly in the Relay scope.
My general question is: how do you go in handling filtering and especially sorting the Relay way (if at all) and why?
Lets say we could query with a Relay server like:
I guess my questions are:
AGE
would be an Enum value) or would be querying for a differentfirendsOrderedByAge
connection be more aligned with Relay philosophy? Or what else?friends(order:[AGE,POSTCOUNT], ...)
Connection
model, how would you go in building a backend API that does?{after_age, after_id}
from your opaque cursor in theafter
parameter; would a pseudo-SQL like this make sense?SELECT * FROM a_table WHERE (age, id) > (after_age, after_id) ORDER BY age ASC, id ASC LIMIT first
Thank you all!
The text was updated successfully, but these errors were encountered: