Skip to content
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

[API] Subscribe with arguments (real time filtering) #580

Open
chiragmittal19 opened this issue Jun 16, 2020 · 8 comments
Open

[API] Subscribe with arguments (real time filtering) #580

chiragmittal19 opened this issue Jun 16, 2020 · 8 comments
Labels
api feature-request Request a new feature GraphQL API Related to the API (GraphQL) category/plugins

Comments

@chiragmittal19
Copy link

chiragmittal19 commented Jun 16, 2020

There should be a way to pass arguments to subscriptions so that only a subset is subscribed.

Model schema -

type MyData @model {
  id: ID!
  x: Int
  other_data: String
}

Subscription method onUpdateMyData which take an input parameter x -

type Subscription {
    onUpdateMyData(x: Int): MyData
        @aws_subscribe(mutations: ["updateMyData"])
}

Mutation method updateMyData -

type Mutation {
    updateMyData(input: UpdateMyDataInput!, condition: ModelMyDataConditionInput): MyData
}

Following the official documentation, I wrote the below code for subscription. Works as expected, i.e, gets triggered whenever the updateMyData mutation is called, irrespective of the value of x.

Amplify.API.subscribe(ModelSubscription.onUpdate(MyData::class.java),
    { Log.i("ApiQuickStart", "Subscription established") },
    fun(onUpdate: GraphQLResponse<MyData>) {
        if (onUpdate.hasData()) {
            Log.i("ApiQuickStart", "Update: " + onUpdate.data.toString())
        } else if (onUpdate.hasErrors()) {
            Log.e("ApiQuickStart", "Error: " + onUpdate.errors.joinToString { it.message })
        } else {
             Log.i("ApiQuickStart", "Null update")
        }
    },
    { onFailure -> Log.e("ApiQuickStart", "Subscription failed", onFailure) },
    { Log.i("ApiQuickStart", "Subscription completed") }
)

But the problem is, I only want to subscribe for a specific value of x, say 5.
So, I tried by modifying the request -

ModelSubscription.onUpdate(MyData::class.java).apply {
    putVariable("x", 5)
}

This made no difference. I'm still receiving updates for other values of x.

This is how I call updateMyData mutation from AppSync console -

mutation {
  updateMyData( input: {
    id: 1,
    x: 5,
    other_data: "some updated info"
  } ) {
    id, x, other_data
  }
}

Subscription in AppSync console works like a charm, i.e, it gets triggered only for a subset where x = 5 -

subscription {
  onUpdateMyData(x: 5) {
    id, x, other_data
  }
}

Just to mention, DynamoDB is used as the data source.

@jamesonwilliams
Copy link
Contributor

jamesonwilliams commented Jun 16, 2020

@chiragmittal19

We could add a filtering argument to ModelSubscription.onUpdate(...), like:

public static <M extends Model> GraphQLRequest<M> onUpdate(
        Class<M> modelType, QueryPredicate filter) {
    ...
}

Is this what you have in mind?

This would constrain the set of results returned over the network, by means of a GraphQL predicate.

Since we don't have that, for the time-being, you could do the filtering on the client. I recommend using the Rx Bindings for this.

RxAmplify.API.subscribe(onUpdate(MyData::class.java))
    .filter { post -> !post.hasErrors() && post.hasData() }
    .map { post -> post.data }
    .filter { data -> data.x == "5" }
    .subscribe(
        { Log.i("Demo", "Found a match: $it") },
        { Log.i("Demo", "No matches.", it) }
    )

@jamesonwilliams jamesonwilliams added GraphQL API Related to the API (GraphQL) category/plugins feature-request Request a new feature labels Jun 16, 2020
@chiragmittal19
Copy link
Author

A QueryPredicate sounds good. But in terms of performance and cost, will that be equivalent to passing an argument to the subscription method?

I guess it would be better to have an option to pass the complete string, maybe like this -

String subscriptionString = 
  ```subscription {
       onUpdateMyData(x: 5) {
         id, x, other_data
       }
     }```

Amplify.API.subscribe(subscriptionString,
    { Log.i("ApiQuickStart", "Subscription established") },
    fun(onUpdate: GraphQLResponse<MyData>) {
        if (onUpdate.hasData()) {
            Log.i("ApiQuickStart", "Update: " + onUpdate.data.toString())
        } else if (onUpdate.hasErrors()) {
            Log.e("ApiQuickStart", "Error: " + onUpdate.errors.joinToString { it.message })
        } else {
             Log.i("ApiQuickStart", "Null update")
        }
    },
    { onFailure -> Log.e("ApiQuickStart", "Subscription failed", onFailure) },
    { Log.i("ApiQuickStart", "Subscription completed") }
)

@jamesonwilliams
Copy link
Contributor

@chiragmittal19 Thanks for the feedback! We prioritize work based on the number of reactions an issue receives. I'll close this issue for now, but let's leave it as a feature request.

If you are reading this and would like to see this feature implemented, please add a 👍 here: #580 (comment)

@nin234
Copy link

nin234 commented Jul 26, 2020

Yes would like this feature. Very helpful to reduce network traffic

@w-okada
Copy link

w-okada commented Sep 12, 2020

I also want this feature. Maybe this feature makes more secure in addition to moderating network traffic.

@richardmcclellan richardmcclellan changed the title Subscribe with arguments [API] Subscribe with arguments (real time filtering) Feb 23, 2021
@SteveJamesDev
Copy link

SteveJamesDev commented Aug 31, 2022

For anyone who finds themselves here... AppSync has a feature that MIGHT help you like it helped me

https://docs.aws.amazon.com/appsync/latest/devguide/extensions.html

$extensions.setSubscriptionFilter

It allows you to add additional filters on the server side

@lawmicha lawmicha added the api label Sep 7, 2022
@vibhorkhurana580
Copy link

@jamesonwilliams Any update on the feature Request?

@jamesonwilliams
Copy link
Contributor

Hey, @vibhorkhurana580 - sorry, I haven't worked on this project in a number of years. Overall I'd encourage folks to migrate to Apollo Kotlin, which also supports AppSync's flavor of WebSockets if you're stuck on that backend for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api feature-request Request a new feature GraphQL API Related to the API (GraphQL) category/plugins
Projects
None yet
Development

No branches or pull requests

7 participants