0

I am working on a messaging app using AWS AppSync.

I have the following message type...

type Message
    @model
    @auth(
        rules: [
            { allow: groups, groups: ["externalUser"], operations: [] }
        ]
    ) {
    id: ID!
    channelId: ID!
    senderId: ID!
    channel: Channel @connection(fields: ["channelId"])
    createdAt: AWSDateTime!
    text: String
}

And I have a subscription onCreatemessage. I need to filter the results to only channels that the user is in. So I get a list of channels from a permissions table and add the following to my response mapping template.

$extensions.setSubscriptionFilter({
    "filterGroup": [
        {
           "filters" : [
                {
                    "fieldName" : "channelId",
                    "operator" : "in",
                    "value" : $context.result.channelIds
                }
           ]
        }
    ]
})

$util.toJson($messageResult)

And it works great. But if a user is in more than 5 channels, I get the following error.

{
    "message": "Connection failed: {"errors":[{"message":"subscription exceeds maximum value limit 5 for operator `in`.","errorCode":400}]}"
}

I am new to vtl. So my question is, how can I break up that filter in to multiple or'd filters?

Bob
  • 45
  • 1
  • 5

2 Answers2

0

According to Creating enhanced subscription filters, "multiple rules in a filter are evaluated using AND logic, while multiple filters in a filter group are evaluated using OR logic".

Therefore, as I understand it, you just need to split $context.result.channelIds into groups of 5 and add an object to the filters array for each group.

Here is a VTL template that will do this for you:

#set($filters = [])

#foreach($channelId in $context.result.channelIds)
  #set($group = $foreach.index / 5)
  
  #if($filters.size() < $group + 1)
    $util.qr($filters.add({
          "fieldName" : "channelId",
          "operator" : "in",
          "value" : []
      }
    ))
  #end

  $util.qr($filters.get($group).value.add($channelId))
#end

$extensions.setSubscriptionFilter({
    "filterGroup": [
        {
           "filters" : $filters
        }
    ]
})

You can see this template running here: https://mappingtool.dev/app/appsync/042769cd78b0e928db31212f5ee6aa17

(Note: The Mapping Tool errors on line 15 are a result of the $filters array being dynamically populated. You can safely ignore them.)

Zac Charles
  • 1,208
  • 14
  • 19
0

Do you want to add server-side filter for GraphQL Subscriptions? If so, Now, Amplify is supported for server-side filter for Subscriptions. After you checking below blog, you may sense it. https://aws.amazon.com/blogs/mobile/announcing-server-side-filters-for-real-time-graphql-subscriptions-with-aws-amplify/