aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.81k stars 821 forks source link

Datastore and Multi-tenancy with combo keys #6225

Closed amirmishani closed 3 years ago

amirmishani commented 3 years ago

Which Category is your question related to? Datastore

Amplify CLI Version 4.39.0

What AWS Services are you utilizing? API

I have two questions:

  1. Is Datastore using the generated appsync resolvers in the backend? In a multi-tenant scenario where I would normally have to add additional security constraints and manually adjust the VTL resolvers, would that also secure or perhaps break the Datastore functions or are they not related at all?

  2. Again in the multi-tenant scenario where I need to have combo keys, I would like to know how I can properly set that up since I noticed the following while I was looking at relational models docs:

When using the @key directive with DataStore, as long as you specify a name you can use any value(s) in fields. However, if the name property is omitted, the first item in the fields array must be "id". E.g., @key(fields: ["id", "content"]).

My schema is for a multi-tenant setup requires a hash-sort combo key with the tenantId being the hash and looks something like this:

type Tenant @model {
   id: ID!
   # ... more fields
}

type User @model @key(fields: ["tenantId", "id"] {
   tenantId: ID!
   id: ID!
   # ... more fields
}

So my question is that is it just about the name of the field being id or does the docs mean that the unique id must always be the hash field? I guess I'm asking whether renaming the uniqueId to userId and renaming the tenantId to id and changing the schema to looks like the following would work:

type User @model @key(fields: ["id", "userId"] {
   id: ID!
   userId: ID!
   # ... more fields
}

Or is there a deeper issue? For example I know in Apollo if you change the uniqueId field name to something other than "id" can mess with your cache so you would need to specifically tell Apollo to replace id with userId using dataIdFromObject in your client configuration.

Also how do things like DataStore.observe(Post) and DataStore.observe(Post, id) work in this type of multi-tenant combo key scenario?

akshbhu commented 3 years ago

To answer few of your questions

Is Datastore using the generated appsync resolvers in the backend? In a multi-tenant scenario where I would normally have to add additional security constraints and manually adjust the VTL resolvers, would that also secure or perhaps break the Datastore functions or are they not related at all?

1) Yes, Datastore using the generated appsync resolvers in the backend but when syncing for local database to dynamoDB. If manually adjusting the VTL resolvers will also works fine and wont break datastore if the input/output types are being respected ( depends on your the implementation too).

For the next Question:

I guess I'm asking whether renaming the uniqueId to userId and renaming the tenantId to id and changing the schema to looks like the following would work:

Thats not going to work id key work is specific to the Type in your case User.

I guess you are looking for 1:M relationship , you can schema like this :

type Tenant @model {
   id: ID!
   # ... more fields
}

type User @model @key(name : ByTenant, fields: ["tenantId", "id"] {
   tenantId: ID!
   id: ID!
   # ... more fields
}

Having a name keyword in the @key argument denotes the creation of GSI with hashKey and sortKey as parameters present in fields Array(in above case tenantId as hashKey and id as sort key ) For more information on keys , Here is the documentation: https://docs.amplify.aws/cli/graphql-transformer/key

For next set of question

Also how do things like DataStore.observe(Post) and DataStore.observe(Post, id) work in this type of multi-tenant combo key scenario?

Tagging @iartemiev Can you answer this^ ?

cc @undefobj

akshbhu commented 3 years ago

Closing this as there is no activity. Feel free to comment if you have any question regarding this and I will reopen it again.

Statsministeriet commented 3 years ago

I think the question with using the DataStore library with DataStore.observe(Post, id) is pretty relevant. I cannot find anything in the DataStore library documentation regarding this issue.

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels for those types of questions.