Requirements


Functional Requirements:


  • Allow users to tweet messages up to 140 characters.
  • Enable users to follow other users. Or unfollow them
  • Allow users to like tweets from other users. Or unlike tweets
  • Display tweets from followed users in the home feed.
  • Show top K popular tweets in the home feed based on likes and followers.
  • Users should be allowed to delete their tweets
  • Users should be allowed to create accounts, they should also be allowed to delete accounts. If their accounts are deleted
  • Should have the ability to search for an account
  • Should have the ability to search for an


Non-Functional Requirements:


  • Low latency, fairly reliable, scalable
  • The The top K tweets should be updated fairly often
  • Should not be able to find deleted tweets
  • Should not be able to find deleted accounts


API Design

POST /tweet

body : {

message: string

}

returns: 200 OK (with twitter ID, tweetId)


POST /follow

body: {

followerId: string

followeeId: string

}

returns 404 not found (if followerId/followeeId does not exist), else 200 OK


POST /unfollow

body: {

followerId: string

followeeId: string

}

returns 404 not found (if followerId/followeeId does not exist), else 200 OK


POST /like

body: {

tweetId: int

}

returns: 404 not found (if tweetId not found), else 200 OK


POST /unlike

body: {

tweetId: int

}

returns: 404 Not found (if tweetId not found), else 200 OK


GET /get-tweets

body: {

userId: string

page: int (each page has k tweets)

}

return 200 OK with k tweets


DELETE /delete-tweet

body : {

tweetId: int

}

return 200 OK if tweet exists, else 404 Not found


POST /create-account

body: {

userId: string

}

return 200 OK if userId does not exist, else 400 bad request


DELETE /delete-account

body: {

userId: string

}

return 200 OK if userId exists, else 400 bad request


GET /search-account

body: {

prefix: string

}

return 200 OK with list of accounts matching prefix string, else return 404 not found


GET /search-tweet

body: {

prefix: string

}

returns 200 OK with list of tweet matching prefix string, else return 404 not found


High-Level Design

POST /tweet

body : {message: string}

returns: 200 OK (with twitter ID, tweetId)

  1. Client performs input validation (no more than 140 characters), if input validation fails throw frontend error
  2. Sends tweet to API gateway which is sent to server
  3. Server assigns it a unique int tweetId, server updates tweet database, follower database to link the newly created tweet with the follower


POST /follow

body: {

followerId: string

followeeId: string

}

returns 404 not found (if followerId/followeeId does not exist), else 200 OK

  1. Client sends API request to gateway, which routes it to follower server
  2. follower server updates follower database


POST /unfollow

body: {

followerId: string

followeeId: string

}

returns 404 not found (if followerId/followeeId does not exist), else 200 OK

  • Same flow as /follow


POST /like

body: {

tweetId: int

}

returns: 404 not found (if tweetId not found), else 200 OK

  1. Client sends request to gateway which routes it to tweet server
  2. tweet server queries database for that tweet, database updates the number of likes the tweet has, tweet server also updates the follower database to indicate that this user liked this tweet


POST /unlike

body: {

tweetId: int

}

returns: 404 Not found (if tweetId not found), else 200 OK

  • similar format as /like, just the opposite


GET /get-tweets

body: {

userId: string

page: int (each page has k tweets)

}

return 200 OK with k tweets

  1. first route the request to the follower CRUD server
  2. pull up all accounts the person follows from the follower database
  3. Pull up all tweets associated with the followers from the tweet database, return k tweets with the most likes, if some tweets are not found, ignore


DELETE /delete-tweet

body : {

tweetId: int

}

return 200 OK if tweet exists, else 404 Not found

  1. Route to tweet service
  2. tweet service will delete that tweet


DELETE /delete-account

body: {

userId: string

}

return 200 OK if userId exists, else 400 bad request

  1. Route to follower service
  2. delete that entry from database


POST /create-account

body: {

userId: string

}

return 200 OK if userId does not exist, else 400 bad request

  • reverse logic of /delete-account


GET /search-account

body: {

prefix: string

}

return 200 OK with list of accounts matching prefix string, else return 404 not found

  • route to follower database
  • search for all accounts with matching prefix string


GET /search-tweet

body: {

prefix: string

}

returns 200 OK with list of tweet matching prefix string, else return 404 not found

  • route to tweet servce and search in tweet database for all tweets that contain that prefix string


API gateway

  • responsible for routing requests to correct server


Tweet CRUD service

  • responsible for keeping track of tweets added and deleted
  • can cache database entries for more optimal performance


Follower CRUD service

  • responsible of keeping track of who follows who, making new accounts and deleting accounts
  • can cache database entries for more optimal performance


Detailed Component Design

Tweet CRUD server

  • Generally tweets retrieved are cached
  1. When a tweet is added, its tweetId and mesage are stored in the cache, when deleted this cache is updated
  2. Can store a Trie of all tweets for fast search queries


Follower database

  • there is also caching
  1. Can query tweet CRUD server for tweet information (likes etc.)