Open JimmyHurrah opened 5 years ago
@JimmyHurrah -- I suspect you've found a bug in the emulator. If I understand you correctly, the following needs to be changed:
1) subscription resolver should always return the payload of the mutation
Could you explain in a little more detail, or provide code examples regarding the triggering of the subscription resolver?
As I understand things, its okay if the subscription resolver is triggered, it only matters that clients subscribing to these resolvers can receive the data after initiating a subscription via web socket.
@cbaron Your understanding of the problem is spot on. It does not really matter if the resolver is triggered as long as the response is from the mutation.
I guess the easiest way to reproduce this would be to have a mutation with a subscription where the subscription response mapping always returns null
Maybe a log from when I trigger a mutation will help.
I have a subscription called onMessage
which subscribes to a mutation createMessage
where the request mapping for the subscription only returns null
Heres the output from sending the mutation:
● start graphql
mutation createMessage($conversationid: ID!, $text: String!) {
createMessage(conversationid: $conversationid, text: $text) {
_id
text
__typename
}
}
● start Resolve: Mutation.createMessage [createMessage]
ℹ info Rendered Request:
{ version: '2017-02-28',
operation: 'Invoke',
payload:
{ type: 'Mutation',
field: 'createMessage',
args: { conversationid: '1', text: 'Test' },
source: {},
} }
ℹ info Dispatch to source { name: 'Resolvers', type: 'AWS_LAMBDA' }
Received payload {} {"type":"Mutation","field":"createMessage","args":{"conversationid":"1","text":"Test"},"source":{}}
ℹ info Rendered Response:
{ conversationid: '1',
author: '1',
createdAt: '2019-03-10T21:56:45.603Z',
text: 'Test',
_id: '1' }
● start Resolve: Subscription.onMessage [onMessage]
ℹ info Dispatch to source { name: 'Resolvers', type: 'AWS_LAMBDA' }
Received payload {} {"type":"Subscription","field":"onMessage","args":{"conversationid":"1","author":"1","createdAt":"2019-03-10T21:5
ℹ info Rendered Request: { authorized: true }
ℹ info Rendered Response: null
ℹ info publish
{ payload: { data: { onMessage: null } },
clientId: '1234567890',
topicId: '88f5b85f-7a40-491b-80d5-c0d3023de867' }
ℹ info client (1234567890) unsubscribed to : 88f5b85f-7a40-491b-80d5-c0d3023de867
ℹ info client disconnected to subscription server (1234567890)
Got it. That shouldn't be too hard to fix in the emulator. I will try to get to it this week. As always, you're welcome to put up a PR as well -- let me know if I can be of assistance.
Also, in the meantime, I think as a workaround you can follow the example laid out in in our unit tests.
Here is the serverless.yml which uses a "pass through" subscription resolver to return exactly the mutation:
dataSource: SubscriberPassthrough
type: Subscription
field: subscribeToPutQuoteRequest
request: subscribePassthrough-request.txt
response: result-response.txt
I tried looking into the subscription code before opening this issue but I couldn't really follow how the pubsub, mqtt and subscription server stuff worked together. I might give it another go later this week.
Thanks for the workaround, it works as expected 👍
When running a mutation that has a subscription it seems to trigger the subscription resolver, I'm under the impression that the subscription resolver should only be triggered on the initial subscription registration and that the data published to the subscription should be the return payload of the mutation.
From the appsync devguide "Subscriptions are triggered from mutations and the mutation selection set is sent to subscribers." ... "Although the subscription query is needed for client connections and tooling, the selection set that is received by subscribers is specified by the client triggering the mutation."
I use a resolver to authorize subscriptions as described in the security section of the devguide response mapping returns
null
to continue or$utils.unauthorized()
to fail.It seems the emulator is using the resolver mapping for the subscription on the data, which in my case results in the published data to be
null
My code works fine in appsync but not in the emulator, Any thoughts on this?