Amplify-android: Subscribe with arguments

Created on 16 Jun 2020  路  5Comments  路  Source: aws-amplify/amplify-android

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.

API Feature Request

Most helpful comment

@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: https://github.com/aws-amplify/amplify-android/issues/580#issue-639443740

All 5 comments

@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) }
    )

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") }
)

@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: https://github.com/aws-amplify/amplify-android/issues/580#issue-639443740

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

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

Was this page helpful?
0 / 5 - 0 ratings