trucha
trucha

Reputation: 31

AWS AppSync enhanced subscription filter not working

Implementing subscriptions for AWS AppSync I use the enhanced filter capability to filter out tasks, that does not belong to a specific user.

To distinguish between users an ID is used in the claims part of the verified JWT that is then parsed in the $context object in the VTL response mapping.

But subscribers will always receive all objects that are created without the filter taking effect.

Our graphql schema (simplified) is looking like this

type Mutation {
    createTask(
        done: Boolean!,
        due: String!,
        id: String!,
        identityId: String!,
        read: Boolean!,
        note: String!,
    ): Task
}

type Subscription {
    create: Task
        @aws_subscribe(mutations: ["createTask"])
}

type Task @aws_iam
@aws_oidc {
    identityId: String!
    done: Boolean
    due: String
    id: String
    read: Boolean
    note: String
}

The datasource for the subscription resolver is a NONE datasource and the request and response mappings are the following:

Request:

{
    "version": "2017-02-28"
}

Response:

$extensions.setSubscriptionFilter({
  "filterGroup": [
    {
      "filters" : [
        {
          "fieldName" : "identityId",
          "operator" : "eq",
          "value" : $context.identity.claims.identityId
        }
      ]
    }
  ]
})

$util.toJson($context.result)

With this enhanced filter I expect AppSync to filter out all tasks where the identityId does not match the one in the token... but that does not work for any reason.

What do i miss?

Upvotes: 1

Views: 781

Answers (1)

trucha
trucha

Reputation: 31

After a long search and almost giving up, I found the solution myself.

It's all about the correct composition of the payload attribute in the request mapping.

Without the payload object one could not access the claims in the identity part of the context object. Or at least the filtering doesn't seem to work.

Finally my request mapping looks like this:

{
  "version" : "2017-02-28",
  "payload" : {
     "resultList" : $util.toJson($context.result),
     "idnId" : "$context.identity.claims.identityId"
  }
}

And in the response mapping

$extensions.setSubscriptionFilter({
   "filterGroup": [{
      "filters" : [{
         "fieldName" : "identityId",
         "operator" : "eq",
         "value" : $context.result.idnId
    }]
  }]
})

$util.toJson($context.result.resultList)

I can then access the two objects.

So the filtering now works as expected.

enter image description here

Upvotes: 2

Related Questions