Planned module: @dataplan/graphql
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 625
- Avg merge
- 5h 23m
- Merged PRs (30d)
- 24
Description
### Summary
**Grafast Question: What is the best way to get or assemble the accessed fields from the finalized plan?**
HI @benjie, awesome work here! I'm excited for the future of grafast, its a novel solution to the continual pains of graphql resolution.
#### Example Case Question
Our team is writing a small service-specific graphql api wrapping our larger core graphql api. The schema will largely be a subset of the core schema, but with many fields filtered out and others added for denormalization / business logic. We've explored delegation, federation, and stitching, but all those seem rather bloated for our use case.
I was wondering if you have suggestions on using grafast steps to build up a dynamic query to another graphql server. I suspect this is theoretically very similar to pg planning.
Here is a somewhat contrived example schema for the service-specific api using grafast:
```typescript
const typeDefs = /* GraphQL */ `
type Query {
order(id: Int): Order
}
type Order {
id: Int
name: String
customer: Customer
}
type Customer {
id: Int
name: String
displayName: String
}
`
const plans: GrafastPlans = {
Order: {
id: ($order: ObjectLikeStep) => {
return $order.get('id')
},
name: ($order: ObjectLikeStep) => {
return lambda([$order.get('id')], ([id]) => {
return `Order #${id}`
})
},
customer($order: ObjectLikeStep) {
return $order.get('customer')
},
},
Customer: {
id: ($customer: ObjectLikeStep) => {
return $customer.get('id')
},
name: ($customer: ObjectLikeStep) => {
return $customer.get('name')
},
displayName: ($customer: ObjectLikeStep) => {
const $name = $customer.get('name')
const $region = $customer.get('region')
return lambda([$name, $region], ([name, region]) => {
return `${name} (${region})`
})
},
},
Query: {
order(_, fieldArgs, _builder) {
const $id = fieldArgs.get('id')
return loadOne($id, async (specs, options) => {
const someSelectFromAccessedFieldsInDag = {
// How to fetch full select here?
}
const query = jsonToGraphQLQuery({
query: {
order: {
__args: {
id: $id,
},
...someSelectFromAccessedFieldsInDag,
},
},
})
return client.execute(query)
})
},
},
}
```
And given the following example query to the grafast api:
```graphql
query order($id: Int) {
order(id: $id) {
name
customer {
name
displayName
}
}
}
```
That query assembles a plan with `$order.id`, `$order.customer`, `$customer.name` and `$customer.region`.
Given that, the desired query to the core graphql api would be:
```graphql
query order($id: Int) {
order(id: $id) {
id
customer {
name
region
}
}
}
```
What would be the best way to assemble the full set of fields accessed from the `Query.order` step? Can that be done by walking the plan itself, or do we need to use a custom step class to track and assemble the core api query?
Thanks!
Contributor guide
Assessment
This issue has not been assessed yet.