Requirements: Design a REST API service from the ground up (assume it can publicly be accessed via HTTP). The REST API has two functions:
saveEvent (user_id, key, value, [{subkey,subvalue},{subkey,subvalue},…]) The saveEvent call will accept a user_id, a key, a value and an optional array of subkeys and subvalues.
getEvent (user_id, key || subkey, date_min, date_max) The getEvent call will return the sum of all the values for that user / key cominbation for that date range (and will support both key and subkey).
Solution:
Possible Candidates for DataStore. Given the type of data the most obvious candidates are any generic Key/Value store or a NoSQL database.
1) For our case I would go with MongoDB a NoSQL database which can Scale horizontally. Since we are doing some kind of aggregation with respect to user_id and key/subkeys having a db with rich query interface would make our job easier as compared to Key Value stores.
Given that the system need to scale we can use the Sharding feature of MongoDB so as to distribute the data across different machines and hence load balance the system.
2) Choice of MongoClient : Mongoose. Provides a simple apis for querying db.
3) Express framework for providing the REST type API’s.
4) Depending on the number of Cores we could create those many Node.js process fronted by Nginx server. All the node.js process talk to a single Mongo backend.
5 ) Demo of the app available on Heroku. Using the shared instance of MongoLab for the demo.
Example:
FOR saveEvent: curl http://hollow-meadow-3903.herokuapp.com/saveEvent -XPOST -d “user_id=shrikar&key=shrek&value=100&optional=[{shrek,50},{subkey1,33 } ]” Event Saved.
For getEvent: curl “http://hollow-meadow-3903.herokuapp.com/getEvent?user_id=shrikar&key=shrek&start=2012-04-29T02:50:42.749Z&end=2012-04-29T010:11:16.262Z” {“sum”:150}