-
Notifications
You must be signed in to change notification settings - Fork 28
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
Use query fragments instead of strings to merge/combine queries #439
Comments
Would it work with Cylc UI (i.e. Vue.js, ApolloClient, Babel, Webpack, etc, etc?)First PoC, to confirm it works with Cylc UI. https://github.com/kinow/cylc-ui/compare/master..graphql-tag-1 (disabled GScan as otherwise it would try to merge So instead of parsing subscription TreeView ($ids: [ID]) {
workflows (ids: $ids) {
...workflowData
...treeData
}
} That could actually be the root query of the Then the view must add the fragments. The equivalent query in GraphiQL would be subscription TreeView ($ids: [ID]) {
workflows (ids: $ ids) {
...workflowData
...treeData
}
}
fragment workflowData on Workflow {
id
name
status
owner
host
port
}
fragment treeData on Workflow {
cyclePoints: familyProxies(ids: ["root"]) {
cyclePoint
}
taskProxies(sort: { keys: ["cyclePoint"] }) {
id
name
state
cyclePoint
latestMessage
firstParent {
id
name
cyclePoint
state
}
task {
meanElapsedTime
name
}
jobs(sort: { keys: ["submit_num"], reverse:true }) {
id
batchSysName
batchSysJobId
host
startedTime
submittedTime
finishedTime
state
submitNum
}
}
familyProxies (exids: ["root"], sort: { keys: ["firstParent"]}) {
id
name
state
cyclePoint
firstParent {
id
name
cyclePoint
state
}
}
} With variables: {
"ids": ["kinow|five"]
} |
Would we be able to merge the objects?See related issues/comments, which show that we are not the only ones trying to achieve this.
Was going to start working on a Codepen example, but turns out
Each view would use 1 query (so far, every view we have use the same query/subscription type of subscription {
workflows {
id
name
// fragments expanded here
}
}
//fragments go here Then besides the query of the view, each view (or component) would tell the We would only need to replace where it says that fragments go, or are expanded. The final query would look like: subscription {
workflows {
id
name
...View1Data
...View2Data
}
}
fragment View1Data on Workflow {
status
taskProxies {
jobs (sort: { keys: ["submit_num"], reverse:true }) {
id
}
}
}
fragment View2Data on Workflow {
port
taskProxies {
jobs (sort: { keys: ["submit_num"], reverse:true }) {
id
cyclePoint
}
}
} Why is that a good idea?
IOW, if you have: jobs (sort: { keys: ["submit_num"], reverse:true }) {
id
} And you have another fragment with jobs {
id
} The query fails to run, so unit and/or functional tests will fail. Which is better than having possible undesired behaviour in runtime (if not caught by any tests).
The major downside for this approach is that it requires quite a lot of modifications in the WorkflowService and views/components using it. So probably an issue for 0.3 or later. |
Yesterday created some code to merge queries programmatically. It stops shy of working, just needs to merge the selection nodes. A GraphQL query has an operation definition, that contains a selection set. The selection set includes fields and fragments, recursively. This is the tricky part... I found some libraries that could be used to simplify it. But I realized there could be a simpler approach. But the work is saved in a branch. https://github.com/kinow/cylc-ui/tree/graphql-tag-2 |
Today I started the different approach, using a higher order component. What's interesting about this approach, is that it requires changes that are in other issues/pull requests. Like better organize the mixins, which was done in #672 (I cherry-picked commits from that branch), and also have a unique way to handle deltas, which would also fix #684 . The HOC function is almost ready for a test I think, but still need to combine fragments. The idea is, instead of merging objects, which can be hard, we simply add the fragments to a set. And then expand the base query. This base query has the following form:
This query retrieves workflows, in a deltas-subscription, for a single workflow (filtered by a variable). What I am aiming for, in this branch, is to have a view like
And then programmatically the component, upon creation, will know that it needs to combine all the fragments provided, creating the final GraphQL query to be used in the subscription. Work being pushed to https://github.com/kinow/cylc-ui/tree/graphql-tag-3 |
@kinow have you seen this? https://github.com/domasx2/graphql-combine-query |
Yup, but thanks for posting it here! It was one of the libs I found when searching for someone doing the same thing we are doing. I will explain tonight the current approach. It's not merging queries, instead it's combining fragments. But there's one downside that I want to check with others. If we really have to merge it, then I will either convert queries to JSON and merge (what we do today), implement the merging of fragments/selection sets (fields of a query), or use that library 👍 |
(that library appeared in a few places actually, SO answers and GH replies; for more: #439 (comment)) |
|
https://github.com/svt/graphql-defragmentizer looks useful, but still not quite what we want. From what I understood, it would require us to create JS objects that are then combined. It's an extra layer on top of |
Describe exactly what you would like to see in an upcoming release
Investigate using
graphql-tag
to merge queries.That would allow us to use any sorting keys (#300), use variables (#234), and use
graphql-tag
imports instead of strings (#356).And maybe with more work we can fix #209 and #417 too.
Additional context
i. Queries will have the same operation type
subscription
, and will/must share the root level field. The root level will beworkflow
. For example:ii. Variables must match. Meaning, too, that we are not merging a query like GScan's, that doesn't have any variables, with a query that is limited for a single workflow like the Tree view query. So the following example will result in an error.
iii. Queries must reuse/share fragments. So that we can define what is a
Job
and use it in a Tree view query, or Graph view query, etc (this is partially done already).Pull requests welcome!
The text was updated successfully, but these errors were encountered: