-
Notifications
You must be signed in to change notification settings - Fork 1.1k
query based on fields of complex variables #248
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
Comments
I guess I'm trying to figure out if you're only using the name why you wouldn't just pass in the name instead of the whole complex input? |
@benwilson512 The query is an extension point of our backend service. The developer should be able to use any number of variables in the query but isn't required to use all of them. One way to handle this is to have a separate ui where the developer picks exactly the variables they want included and we include these as individual variables. There are two reasons I won't to avoid this approach. 1) it introduces extra ui. 2) we would have to prefix the variables as they are now top level and could conflict with other variables we would add in the future. Is this use case clear or should I try to make it more concrete? The cleanest solution I could come up with for our use case is to allow accessing fields of variable objects in the query. My proposed syntax aligns with the proposal in #174 to enable flattening of object arrays |
Isn't that just solved by doing:
And having the resolvers handle the fact that their inputs are nested 1 layer deep? I guess my overall feeling here is that this is new syntax, new validation rules, and several other new capabilities to solve a problem that would be solved by either having a more nuanced client or by just nesting. |
The issue with that solution is that the The Dog example is simple and doesn't make too much sense, but should illustrate what we are trying to do. |
In this case Either inline like so: query takesComplexInput($complexInput: { name: String! }) {
findDogByName(name: $complexInput.name) {
name
}
} or with a local type definition: input ComplexInput {
name: String!
}
query takesComplexInput($complexInput: ComplexInput) {
findDogByName(name: $complexInput.name) {
name
}
} |
It certainly has to be defined in the schema. I'm not sure why that is different from the current situation - I'm probably missing something. Could you elaborate? |
This would also be super useful for variables used in directives like For example I'd much prefer this:
Over this:
|
I feel like this would be even cooler with #251 (remove variable definitions) so you could do:
Then you don't even need the input definition. |
Big 👍 to this issue. In our case we we have generic resolvers and want to be able to declaratively map application-specific input types (e.g. values of a form) to a generic GraphQL schema using only the operation definition: input ProductListFilter {
partialName: String
minStarRating: Int
maxPrice: Int
}
query ListProducts($filters: ProductListFilter) {
products(where: {
avgRating: {_gte: $filters.minStarRating},
name: {_like: $filters.partialName},
price: {_lte: $filters.maxPrice}
}) { id, name, price, avgRating }
} The critical idea here is that we want the input to match the shape that makes sense to the client application while translating that to the generic querying system of the resolver. |
@mbleigh Your example doesn't seem particularly compelling, since you could instead issue it using existing syntax with a slight tweak to the variables you supply: query ListProducts(
$partialName: String
$minStarRating: Int
$maxPrice: Int
) {
products(where: {
avgRating: {_gte: $minStarRating},
name: {_like: $partialName},
price: {_lte: $maxPrice}
}) { id, name, price, avgRating }
} Could you expand on why this isn't a suitable solution? When doing so, please keep the Guiding Principles in mind. |
I think the two core issues problems with the existing syntax that I can't address easily are:
In a simple example like the above I'd agree that variables are a reasonable replacement. But in a much more complex UI, I might have 5-6 similarly complex filters / fetches happening at once. Nesting provides much more comprehensible grouping and namespacing for related inputs than, say, using prefixes (e.g. 3 vars with a Let's take a look at another example focused around reusability. We have a system that will automatically generate and expose CRUD operations based on type definitions. So a For application logic, the fields are always going to be the same and can reasonably be mapped to a When I'm consuming these generated mutations (which I don't have direct ability to modify), I want to be able to reuse these same data types but reuse only parts of what's provided based on the specific needs of the operation for the app, and override parts of the input with my own "constants": type Product {
id: ID!
name: String!
description: String
price: Int
inventory: Int
status: ProductStatus!
createTime: Timestamp!
updateTime: Timestamp!
}
# generated automatically
input ProductInput {
name: String
description: String
price: Int
inventory: Int
status: ProductStatus
createTime: Timestamp
updateTime: Timestamp
}
mutation createProduct($data: ProductInput) {
createProduct(data: {
name: $data.name,
description: $data.description,
price: $data.price,
inventory: $data.inventory,
status: PENDING_REVIEW # OrderStatus is fixed and not derived from input
createTime: {now: true} # Timestamp is a scalar with special parsing for this sentinel value
updateTime: {now: true} # Timestamp is a scalar with special parsing for this sentinel value
})
} { ... }
mutation updateProduct($id: ID!, $data: ProductInput) {
updateProduct(id: $id, data: {
name: $data.name,
description: $data.description,
price: $data.price,
inventory: $data.inventory,
updateTime: {now: true}
})
} { ... } Without being able to do property accessors for the input type, I couldn't use the auto-generated input type as a variable and would have to repeatedly define the same set of variables over and over again. |
Thank you for sharing 👍 |
Complex variables are described in the spec https://facebook.github.io/graphql/#sec-Variables-Are-Input-Types
This example takes a ComplexInput and passes it to the findDog query:
What I would really like to do is use specific fields in the ComplexInput variable like this:
This is not valid GraphQL, but it would simplify a feature we are working on quite a bit.
For context: Graphcool is a backend application platform that combines GraphQL and Lambda. Many of our features are based on automatically generated schemas and stored queries we execute on the server in response to some event, so our needs might differ significantly from the broader community.
The text was updated successfully, but these errors were encountered: