amplify-js
amplify-js copied to clipboard
DataStore disable sync for specific models
Is this related to a new or existing framework?
React Native
Is this related to a new or existing API?
DataStore
Is this related to another service?
No response
Describe the feature you'd like to request
I'm using some Models which I want only to be accessible from the lambda function of one custom graphQL endpoint and not directly from the app. I want to give the ability to whitelist domains through amplify studio content. Therefore I've define the model like it's suggested to avoid generating queries, mutations and subscriptions for that model.
type WhitelistedDomains
@model(queries: null, mutations: null, subscriptions: null)
@auth(rules: [{allow: private, operations: [read], provider: iam}]) {
id: ID!
domainURL: String!
}
type Mutation {
verifyEmail(email: String!): ID!
@function(name: "verifyEmail-${env}")
@auth(rules: [{allow: public, provider: apiKey}])
}
I can correctly set whitelisted URLs, and with the custom iam policy at the lambda I can verify that the email is from a whitelisted domain. However when I start using DataStore for other models of the app, the library starts throwing warnings because it can't find the subscriptions to sync the WhitelistedDomains model. If I add the subscriptions it also fails because the model is only authorised through iam and not by apiKey.
Describe the solution you'd like
I would like a way to configure the sync expressions of a model to never try to sync it with the cloud, as it's for backend purposes only.
It could be a defined Predicate as the Predicates.ALL
I think Predicates.NONE
would be good.
And this should disable syncing for that specific model to avoid getting all the warnings.
Describe alternatives you've considered
I've tried to replicate what have been done in the PR fixing the amplify-android library but wouldn't work in my case.
DataStore.configure({
syncExpressions: [
syncExpression(WhitelistedDomains, domain => domain?.id('eq', '')),
],
});
Another solution to avoid the warnings would be to create the subscriptions in graphql and modify the authorisation policy of the model to be able to sync from the app. However this would take unnecessary code and network calls.
Additional context
Something similar has been included in amplify-android with this issue
Is this something that you'd be interested in working on?
- [ ] 👋 I may be able to implement this feature request
- [ ] ⚠️ This feature might incur a breaking change
Related to https://github.com/aws-amplify/amplify-js/issues/6593
We have a model we are using to create one-way backups (similar to revisions) of another model. We don't need to sync this model, as we are only performing actions manually on these backups.
We used the sync expression workaround stated in this issue, and that was successful for preventing the client from getting bogged-down with unnecessary data.
HOWEVER - We released an update about 2 weeks ago that triggers far more backups, and we now have a DynamoDB bill that is through the roof. 1354% increase in cost. And it's all ReadRequestUnits
on the backups table.
Heavy reads on the backup table?? Yep. Because when you use this sync expression workaround, the sync request still fires, and the AppSync resolver scans DynamoDB looking for data that matches your expression. Whoops.
Needless to say, we need a real solution to this.
Considering overriding the sync resolver so that it never actually reaches out to dynamo, it just always returns an empty array... Open to other ideas though
In a similar case, want to skip a @model from scheme on front-end completely and work with it only through back-end.
Found a work around that seems to work, please give me some thought if this approach can backfire somewhere.
We can trick the system the following way:
- amplify push your scheme with the table we wont to skip the sync on
- remove that table from the
amplify/backend/api/{YOUR_API_NAME}/schema.graphql
- run
amplify codegen models
- return the removed model to the
schema.graphql
to not commit the trimmed version - profit - no Model type generated at client, no sync attempts on that model from client.
PLEASE NOTE that this is not supported use case of DataStore. The functionality could change at any time. so use at your own risk (see the following response from @dpilch))
I'll preface this by saying this is not supported use case of DataStore. The functionality could change at any time.
@ArsSirek, I don't see any negative effects as it currently stands (other than the hassle of repeating these steps every amplify push/pull
).
I wouldn't recommend this approach for production apps, but if this is truly your only option I believe it is "safe" for the current version of DataStore. This could change at any point in the future without warning.
Why is this still open? Being able to skip sync of certain models (also conditionally) is such basic thing I would expect from the DataStore syncExpressions. Just make Predicates.NONE and ling the corresponded logic.