List non-functional requirements for the system...
assume:
storage:
REST APIs
all REST API authentication is handled by Bearer token
GET /api/messages/history
HTTP API, cursor-based pagination
request params:
{
group_id: 'g1123', // optional,
from_time: timestamp,
cursor: int,
size: 100,
}
response:
{
pagination: {
next_cursor: int,
},
data: [
{
message_id: 64bit snowflakeid,
content: string,
created_at: timestamp,
},
...
],
status: 0, // success status code
error: '' // error message
}
POST api/groups/create
params
{
group_name: 'group name1',
members: ['u123', 'u444', ...],
}
response
{
group_id: 'g123',
status: 0,
created_at: timestamp,
}
POST api/groups/join
params
{
group_id: 'g123'
}
response
{
status: 0,
}
POST api/groups/quit
params
{
group_id: 'g123'
}
response
{
status: 0,
}
WebSocket
send/receive message
send/receive message via WebSocket connection
client -> server
{
content: 'hi!!',
from_id: 'u112',
to_id: 'u1344'
group_id: 'g455' // optional, message can be a direct message or group message
}
server -> client
{
message_id: 64bit snowflakeid,
content: string,
created_at: timestamp,
}
generic data, e.g. user profile, use relational database because need reliable and robust data storage. utilize replication and sharing to satisfy availability and scalability
for message data, they are:
so we can choose key-value store, also key-value database can:
User
Message
schema:
message_id properties:
we can use 64bit sequence number generator like snowflake
Group
MessageGroup
Key-value store:
<user_id: presence status>
{
user_id1: {
statue: online,
socket_server: socket_server_id1,
last_active: timestamp
}
}
<message_id, message>
{
'111111': {
content: 'hi',
from_id: 'u112',
to_id: 'u45', // to_id is null when is it group chat
group_id: 'g333', gropu_ip is null when it is 1:1 chat
}
}
protocol choice
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
Explain any trade offs you have made and why you made certain tech choices...
Try to discuss as many failure scenarios/bottlenecks as possible.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?