Subscription - server side filtering
I have reviewed:
- https://docs.amplify.aws/swift/build-a-backend/data/custom-subscription/
- https://docs.amplify.aws/swift/build-a-backend/data/subscribe-data/
Also pulled the full Github repo looking for examples but have found none.
Would much appreciate a full example of configuring and using server-side filtering with a subscription on most simple model type, in my case defined as
Event: a
.model({
familyId: a.id().required(),
generatedByMemberId: a.id(),
generatedBy: a.belongsTo('FamilyMember', 'generatedByMemberId'),
type: a.ref('EventType').required(),
metadata: a.string().required(),
family: a.belongsTo('Family', 'familyId'),
})
In my case, I need filtering by familyId.
Thank you.
And regarding https://docs.amplify.aws/swift/build-a-backend/data/custom-subscription/, I applied the customType, mutation and subscription, as well as the receive.js and publish.js files. All deployed fine. However, even though the docs should be on Swift, the code examples are not Swift and I could not find a way to actually use the new subscription/publish/receive in Swift.
Also, once my changes have been deployed, I did not see any additional Lambda deployed for receive/publish. Would appreciate an explanation on how exactly the filtering works on server-side.
This is a major blocker for me atm.
My receive.js looks like this atm
import { util, extensions } from "@aws-appsync/utils"
// Subscription handlers must return a `null` payload on the request
export function request() { return { payload: null } }
/**
* @param {import('@aws-appsync/utils').Context} ctx
*/
export function response(ctx) {
const filter = {
familyId: {
beginsWith: ctx.args.familyId
}
}
extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter))
return null
}
and the I added the following in data/resource
Message: a.customType({
familyId: a.string().required(),
eventName: a.string().required()
}),
// Message publish mutation
publish: a.mutation()
.arguments({
familyId: a.string().required(),
eventName: a.string().required()
})
.returns(a.ref('Message'))
.handler(a.handler.custom({ entry: './publish.js' }))
.authorization(allow => [allow.authenticated()]),
// Subscribe to incoming messages
receive: a.subscription()
// subscribes to the 'publish' mutation
.for(a.ref('publish'))
.arguments({ familyId: a.string() })
// subscription handler to set custom filters
.handler(a.handler.custom({entry: './receive.js'}))
// authorization rules as to who can subscribe to the data
.authorization(allow => [allow.authenticated()]),
Thanks for your question @aneaga. Let me check with the team and get back to you soon.
Hi @aneaga unfortunately we don't support server-side filtering from the Swift library at this time. I'll mark this issue as a feature request and also open an issue to clean up that part of the documentation.
This has been identified as a feature request. If this feature is important to you, we strongly encourage you to give a 👍 reaction on the request. This helps us prioritize new features most important to you. Thank you!
I was testing a less complex use case than you have described, but while we do not provide easy support of subscription server side filtering, it may be possible with custom requests such as this:
let document = """
subscription OnCreateEventBeginsWithName($name: String!) {
onCreateEvent(filter: {name: {beginsWith: $name}}) {
id
name
}
}
"""
let variables = ["name": name]
let request = GraphQLRequest<Event>(document: document, variables: variables, responseType: Event.self)
let subscription = Amplify.API.subscribe(request: request)
@tylerjroach Thanks, but I was not able to have it work, even without any filtering criteria. I believe that may work with Gen1, but I run Gen2.
Also tried the following
let filter = Event.keys.family.eq(familyId)
let request = GraphQLRequest<[Event]>.list(Event.self, where: filter)
let subscription = Amplify.API.subscribe(request: request)
which fails with
GraphQLResponseError<List<Event>>: GraphQL service returned a successful response containing errors: [Amplify.GraphQLError(message: "query not supported through the realtime channel", locations: nil, path: nil, extensions: Optional(["errorType": Amplify.JSONValue.string("UnsupportedOperation")]))]
hi @aneaga From the client side perspective, there is no difference between a gen1 or gen2 backend. If you have the subscription filtering configured on one platform that is working, you should be able to capture the raw graphql document and variables, and replicate the experience. If you want to post any errors you are seeing, let me know.