POST /joinChat -> { chat_id, status: 200}
POST / sendMessage -> 200OK
{
chat_id,
message
}
POST /addFriend/user_id=?
GET /chatHistory
Note: we can use jwt token and encrpt the user id in the header, so that we don't need to put user_id in our request and it is safer.
User table - relational DB partitioned by hash(user_id) % num_db
{
user_id,
name,
email,
gender,
...
}
Friend table - SQL database with ACID
{
user_id, PK
friend_user_id,
createdAt,
updatedAt
}
can have a index user_id-friend_id to quickly search the friendship
Chat table - SQL db partitioned by hash(chat_id) % num_db
{
chat_id, PK
users_list,
createdAt,
updatedAt
}
Chat history table - noSQL for better throughput since it is write heavy
{
chat_id, PK
user_id,
message,
attachment_id,
createdAt, (sort key)
}
Metadata table - noSQL
{
owner_user_id (partition key)
attachment_id,
chat_id,
attachment_type (image, video, file...)
blob_url
createdAt, (sort key)
}
On a high level, we need the belowed components:
User is able to add / remove a friend
User is able to send / receive text messages to his friends
User is able to join / leave a group chat
User is able to send / receive messages in group chat.
User using different devices can sync up the recent messages
Friend Service
Chat Service
Chat Cleanup Service
AttachmentService
The fanout mode of sending messages in a group chat will have a bottlenceks of X users in a group check.
We can either