-
-
Notifications
You must be signed in to change notification settings - Fork 438
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
Add @orderBy argument directive #659
Conversation
How about multiple OrderByClause? |
@robsontenorio What I currently have to get multiple orderBy clauses working is the following: type Query {
suppliers(orderBy: [OrderByClause!]! @orderBy): [Supplier!] @paginate
} I also added an example like this to the docs. Your commend however makes me think that the |
@megawubs i think its better for consistency to always have it as an array. |
@spawnia I agree. But do we require the schema writer to typehint the type, or can we do something like |
What usecase would such a transformation serve, how would it make things easier? Can you give an example? |
@megawubs this is a nice addition, nevertheless I am wondering a bit about the As you might want to control on which field (hopefully indexed) the sorting should be applied to... As an example, here is the implementation used for Github: {
repository(owner: "nuwave", name: "lighthouse") {
issues(last: 100, orderBy: {field: CREATED_AT, direction: DESC}) {
edges {
node {
databaseId
title
createdAt
}
}
}
}
} Checking at: query enumValuesOfIssueOrderField {
__type(name: "IssueOrderField") {
name
enumValues {
name
}
}
} You get: {
"data": {
"__type": {
"name": "IssueOrderField",
"enumValues": [
{
"name": "CREATED_AT"
},
{
"name": "UPDATED_AT"
},
{
"name": "COMMENTS"
}
]
}
}
} What about adding a |
A schema is sometimes easier to describe things 😉 # The default order by direction
enum OrderDirection {
ASC
DESC
}
# A custom order by direction
enum AnotherOrderDirection {
FOO
BAR
}
type Query {
# If orderableEnum is not set, it would default to "OrderDirection"
users: [User!]! @paginate(type: "paginator" model: "App\\User" orderableDirection: "AnotherOrderDirection")
user(id: ID @eq): User @find(model: "App\\User")
}
type User {
id: ID!
name: String!
email: String!
# The default field name will be "CREATED_AT"
created_at: DateTime! @orderable()
# The field name can be overriden
updated_at: DateTime! @orderable(field: "CUSTOM_UPDATED_AT_FIELD_NAME")
}
# This would generate the following enum:
enum UserOrderField {
CREATED_AT @enum(value: "created_at")
CUSTOM_UPDATED_AT_FIELD_NAME @enum(value: "updated_at")
} |
@lucasmichot you bring up some good points. I see the value in having a foolproof schema that uses ENUM's upfront to prevent usage mistakes. The way you propose to define them is quite nice as well. As you correctly noted, it can be beneficiary/necessary for high traffic API's to limit the possible queries. Still, i think the implementation proposed here is close to optimal when it comes to self-consumed API's that should be rapidly developed. A quite common use for Laravel, i think. We can add something like you proposed in a later PR, this one looks fine to me as is. |
Just to come with another alternative This will allow all fields to be ordered
And will generate the following
I can then also just do the following to only order some fields
And it will generate
This approach will also solve the problem of being able to order the same field twice, as that can give confusion to which one of them will run first and last. In theory you could also extend this to also limit if a field should only be able to limit by
And it will generate
And to extend on this a little more, we can then also force a user to choose a orderBy on a field
And it will generate
|
I agree with @spawnia. Ordering by specific fields and directions is a nice thing to have. But for most cases I think it's too much. |
{ | ||
foreach ($value as $orderBy) | ||
{ | ||
$builder->orderBy($orderBy['field'], $orderBy['order']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The directive itself does not require that the type should be OrderByClause
.
If that is the case, then it has to check that the order
is a valid order and also the bigger issue is how does it handle when I input an invalid field
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added validation for a correct definition.
Don't see how invalid fields could be handled gracefully?
* | ||
* @package Tests\Unit\Schema\Directives\Args | ||
*/ | ||
class OrderByDirectiveTest extends DBTestCase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test scenarios looks great. However you are only testing for best case scenarios, we for example also need tests for handling invalid field supplied.
@olivernybroe i like how the fields can be deduced from the model or defined manually in your proposal. However, the spec says that arguments are unordered, so the proposed final schema falls apart there unfortunately. |
@spawnia Ah damn it. But nice catch. Well I guess we need to go with the list approach then as they are ordered. |
@olivernybroe yeah, we can add this in a seperate PR and with a different name, like |
# Conflicts: # src/Schema/AST/ASTBuilder.php
Changes look good to me 😄 |
Thank you @megawubs, great work on this one! 👍 |
Related Issue/Intent
Resolves #580
Changes
@orderBy
argument directiveOrderByClause
input typeSortOrder
enum typeOpen for Discussion
I'm not entirely sure about the naming of the input field type and the enum type yet.
Other possibilities i've tried:
input SortOption
&enum SortOrder
input OrderByOption
&enum OrderByOrder
input OrderByClause
&enum Order
Any other ideas?