aws / aws/aws-appsync-community

Change subscription mapping to match what is returned from the resolver, not what is requested by the user

Open
#89 7 comments 8 reactions 0 assignees View on GitHub
feature-request
Dominant language
HTML
Stars
507
Forks
37
PR merge metrics
No merged PRs in 30d

Description

I'm tempted to label this as a bug, considering how bizarre this behavior is to me, but you can consider this a feature request.

Consider the following example:

type Event {
id: String!
name: String!
description: String
}

type mutation {
createEvent(name: String!, description: String): Event
}

type subscription {
onCreateEvent(name: String!): Event @aws_subscribe(mutations: ["createEvent"])
}

A user can create an event, specifying a name and, optionally, a description. An id is auto-generated for each event in the createEvent resolver.

Suppose Alice wants to subscribe to events that are created with the name "Picnic". She can submit a subscription:

subscription SubscribeToPicnics {
onCreateEvent(name: "Picnic") {
id
name
description
}
}

Suppose Bob goes to create an even with the name picnic. If he uses the following mutation:

mutation CreatePicnic {
createEvent(name: "Picnic", description: "A nice afternoon on the hill") {
id
name
description
}
}

Then Alice will receive a response that looks like:

onCreateEvent: {
"id": "12345",
"name": "Picnic",
"description": "A nice afternoon on the hill",
"__typename": "Event"
}

HOWEVER, suppose Bob instead sends a mutation like this:

mutation CreatePicnic {
createEvent(name: "Picnic", description: "A nice afternoon on the hill") {
id
name
}
}

Then Alice's response will be missing the description field, despite it being returned by the resolver:

onCreateEvent: {
"id": "12345",
"name": "Picnic",
"__typename": "Event"
}

Even worse, if Bob sends a mutation like this (perhaps because he doesn't need the data, he just wants to confirm it has been created):

mutation CreatePicnic {
createEvent(name: "Picnic", description: "A nice afternoon on the hill") {
id
}
}

Then Alice will never receive the real time data of the created event.

Herein lies the problem: Subscription matching as implemented is based on what the CLIENT REQUESTS, rather than what the RESOLVER RETURNS. As a result, the integrity of the subscription system relies on the client. Other than the obnoxious implications for development, this could prove a security risk in certain situations, as it gives the client control over whether a subscription is sent.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the GraphQL examples in the issue with the onCreateEvent subscription and createEvent mutation, varying the mutation's selected fields. Investigate how subscription payloads are matched and assembled from the resolver result versus the client's requested fields. Done means subscribers receive the resolver's returned event data regardless of which fields the mutation requested.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, graphql
Domain
api, backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.