I am working on chat functionality using AWS Amplify and I have a simple Post model in my graphql schema:
type Post
...
{
id: ID!
channelId: ID @index(
name: "byChannel", sortKeyFields: ["createdAt"],
queryField: "listPostsByChannel"
)
customerId: ID @index(
name: "byCustomer", sortKeyFields: ["postType", "createdAt"]
)
text: String!
postTempId: String
postType: String
reactions: [PostReaction] @hasMany(fields: ["id"])
createdAt: AWSDateTime
updatedAt: AWSDateTime
}
What I want to achieve is to have similar to other popular chat apps - reactions with emojis attached to each post, so I've created another table and the PostReaction model.
type PostReaction
...
{
postId: ID! @primaryKey(sortKeyFields: ["customerId", "emojiUnicode"])
customerId: String!
customerMeta: CustomerMeta
emojiUnicode: String!
createdAt: AWSDateTime
updatedAt: AWSDateTime
}
Of course, each customer could add multiple emojis to a single post, the custom primary key is for handling duplicates later.
There is one disadvantage here.
Emojis will be listed in an array in the reactions
field in the post, even if it's the same emoji added by many people.
Instead of a simple array of reactions that frontend would need to merge for each post, the best would be to get a result from the AppSync query for each Post
like:
...
reactions: [{
emojiUnicode: "U 1F44D",
customerIds: ["ID1234", "ID5678"],
...
}, {...}]
I thought that I can use a JSON object in the reactions
field, but the DynamoDB has the max size limit for a single item which is 400KB. That's not a problem for now, but next when I will add more attributes to the Post model, and when there will be many reactions from many people at the same time, this might be an issue.
Is there an option how to achieve this in the simplest way?
CodePudding user response:
Best thing to not over-complicate your schema would be to enforce a maximum number of emojis just as Slack does for example:
You can add up to 23 emoji reactions to any message, but the maximum per message is 50 unique emoji.
Other than that, you could keep an item for each emoji reacted
pk | sk | data |
---|---|---|
thread123 | metadata | metadata about thread |
thread123 | post#001 | First message in thread |
thread123 | post#002 | Second message in thread |
thread123 | post#003 | Third message in thread |
thread123 | post#003#emoji#U 1F44D | [user1, user2, user45] |
thread123 | post#003#emoji#U 1F33R | [user56, user8, user7, user10] |
Now when you want all the data to populate a given thread on your UI, you just issue a query with the pk as a parameter:
SELECT * FROM table WHERE PK = 'thread123'