Comments (9)
There are multiple ways to accomplish this:
- By writing a custom
AsyncIterator
(see here) - By using
withFilter
(see here) - Implement the
resolve
method (see here):
Subscription: {
publications: {
subscribe: async (parent, args, ctx, info) => {
return ctx.db.subscription.post({ }, info)
},
resolve: (payload, args, context, info) => {
// Manipulate and return the new value
return payload;
},
},
},
from prisma-binding.
Thanks so much! 🙏
from prisma-binding.
You're exactly right, @FredyC. This should be a lot easier and will in fact become easier once this issue is tackled: #118
from prisma-binding.
I'm confused how withFilter
would function in conjunction of return ctx.db.subscription.post({ }, info)
- most of the example use cases of withFilter
are tied to returning an AsyncIterator
- is that the responsibility of ctx.db.subscription
somehow?
from prisma-binding.
withFilter
seems to need some handholding to work as I would expect. withFilter
requires a resolved AsyncIterator
, but ctx.db.subscription.link
returns a Promise - so you have to await
. Finally I was surprised that I have to invoke the function filteredSubscription
on the return - it feels like this is different than the usual examples that leverage PubSub - where the function itself is returned.
Can somebody help explain why this works, and if the syntax is expected?
subscribe: async (parent, args, ctx, info) => {
const subscription = await ctx.db.subscription.link(
{ },
info,
)
filteredSubscription = withFilter( () => subscription , (payload, variables) => {
return true
})
return filteredSubscription()
}
from prisma-binding.
I have another question related to this regarding the info
. Consider the following where I want to return an actual type instead of that whole subscription payload as a client doesn't need to know other details about a subscription (eg. kind of mutation, changed fields...).
type Subscription {
onFightStart: Fight!
}
# and query might look like...
subscription {
onFightStart {
id
attackerId
}
}
On the resolver side, it means that info
argument is structured based on my input query and cannot be passed to ctx.db.subscription.fight({}, info)
call directly. I need to somehow transform it so only relevant fields are being queried. I did found this article about demystifying the info
, but it still looks like a lot of legwork and feels like shoving my hands to intestines of something not particularly appealing.
const onFightStart = {
subscribe(_, args, ctx, info) {
const fightIterator = await ctx.db.subscription.fight({}, /* how to build correct info here? */)
const nextFight = async () => {
const { value, done } = await fightIterator.next()
// value is returned in { mutation, node } structure here, not what client wants
const newValue = transformValueByInfo(value, info) // <-- not sure how do this
return { value: newValue, done }
}
return { /* AsyncIterator juggling */ }
}
}
I am aware that if I don't pass any info
argument to prisma binding function, it will create one to contain every scalar field, but that doesn't work with subscriptions as an only scalar field is a mutation
. I had also figured out it's possible to pass a query string to build that info object, but that's hardly flexible. Ideally I want to grab fields that client is asking for.
const selectionSet = `{
mutation
node {
id
attacker {
id
}
}
}`
ctx.db.subscription.fight({}, selectionSet)
from prisma-binding.
@FredyC if I understood you correctly, you have a subscription to the underlying service like this:
type Subscription {
fight: SubscriptionPayload
}
type SubscriptionPayload {
...
node: Fight
}
and want to expose this:
type Subscription {
fight: Fight
}
This means, that the info
object of the resolver for the fight
subscription will contain a query like this:
subscription {
fight {
id
}
}
but the underlying service needs to receive this:
subscription {
fight {
node {
id
}
}
}
In other words, the received query needs to be "embeded" into another query / we need to wrap it.
An API for this could look like this:
const onFightStart = {
subscribe(_, args, ctx, info) {
const fightIterator = await ctx.db.subscription.fight({}, wrapInfo(info, 'node'))
},
resolve(fight) {
return fight.node
}
}
@FredyC does that make sense to you?
from prisma-binding.
You are correct on input information. However, I want to watch for changes in different fields than those requested by the client. I did not realize that before mainly because subscriptions are a bit confusing about this. Data you request will be watched for changes and that's not always what you want.
const onFightStart = {
subscribe(_, args, ctx, info) {
const fightIterator = await ctx.db.subscription.fight({}, watchFragment) // <-- just a string to specify what to watch
const nextFight = async () => {
const { value, done } = await fightIterator.next()
const fight = await ctx.db.query.fight({ where: { id: value.node.fightId } }, info) // <-- use info from client
return { onFightStart: fight }
}
return { /* AsyncIterator juggling */ }
}
}
I don't have any big issue with this right now, it's just kinda unintuitive and I had to spent quite some time to figuring that out and digging in the source code. I just hope that your breaking change in dotansimha/graphql-binding#80 won't prevent me doing this :)
from prisma-binding.
Hey 👋,
I believe the initial question has been well resolved throughout the conversation. In need for gaining a better overview of the issues facing the current version, I'll close it.
Feel free to reopen the issue if you believe we should further discuss its context. 🙂
from prisma-binding.
Related Issues (20)
- how to submit many transactions
- Connect Prisma Bindings to mock server
- Calling a query from Yoga to Prisma does nothing. HOT 5
- Case Sensitive Query Adjustments. HOT 2
- Calling multiple prisma requests returns same error to all the request if any one of them gives error.
- forwardTo() without having to specify resolver keys
- Cannot set property 'fragmentReplacements' of undefined HOT 1
- forwardTo with type rename
- how to get the count of records
- Howto define subscription endpoint
- Sub-selecting custom fields HOT 2
- Subscription Implementation with Prisma Binding
- Improve Code Readability
- error when trying to call aggregate function HOT 1
- Aliases still not works correctly
- How to filter `Where null` HOT 1
- Prisma() not recognized as a constructor HOT 1
- Import error on IResolvers from graphql-tools
- The automated release is failing 🚨
- Version of this for graphql-code-generator ?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from prisma-binding.