Define the APIs expected from the system. This is your chance to analyze and define the read and write paths so that you can come up with the high-level design...
For the API to view connection detail between 2 users, including the number of hops and the shortest connection path:
GET v1/view_connection_details {
current_user_id: UUID,
user_id_B: UUID,
}
For the API to add new connections between users:
POST v1/add_new_connection {
current_user_id: UUID,
user_id_B: UUID,
}
For the API to search for users in the network and retrieving user profiles:
GET v1/search_user {
user_id: UUID,
search_keywords: String
}
For the API to recommend potential contacts based on mutual connections:
GET v1/suggest_potential_contacts {
user_id: UUID
}
Describe the overall system architecture. Identify the main components needed to solve the problem end-to-end. Use the diagramming tool to create a block diagram.
The core of this design is a graph database like Neo4j. Each user is a node in the graph, and each edge is a connection between users.
Schema could be defined like this:
Node user {
user_id: UUID,
user_name: String,
user_metadata: String
}
Edge connection {
user_id_A: UUID,
user_id_B: UUID
}
With a graph database, we store users as nodes and connections as edges. We can leverage the graph database to calculate the shortest connection path between 2 users, as well as the number of nodes between 2 users in minimal latency.
For the write path, when we create a new user, we send traffic to user feed service and user connection service. We do 3 things:
For the write path, when we add a new user connection, we need to trigger 2 flows from user connection service:
For the read path, when we want to view connections between 2 users, or see the shortest path of connection, we query the user connection graph database, and get back results for these queries. Once we have the user_ids, we trigger a request to user feed service, to retrieve the user profile from redis cluster. On cache misses, we query the relational database under it.
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.
The core of this design is a graph database like Neo4j. Each user is a node in the graph, and each edge is a connection between users.
Schema could be defined like this:
Node user {
user_id: UUID,
user_name: String,
user_metadata: String
}
Edge connection {
user_id_A: UUID,
user_id_B: UUID
}
With a graph database, we store users as nodes and connections as edges. We can leverage the graph database to calculate the shortest connection path between 2 users, as well as the number of nodes between 2 users in minimal latency.
For the write path, when we create a new user, we send traffic to user feed service and user connection service. We do 3 things:
For the write path, when we add a new user connection, we need to trigger 2 flows from user connection service:
For the read path, when we want to view connections between 2 users, or see the shortest path of connection, we query the user connection graph database, and get back results for these queries. Once we have the user_ids, we trigger a request to user feed service, to retrieve the user profile from redis cluster. On cache misses, we query the relational database under it.