Node.js + Coffee + mongoDB |
Good morning boys and girls, today I would like to share with you a little something I've been working on.
So I set out to build a web service that would
- Read in a POST request on a Node.js server and save it to a mongo database
- When a GET request comes in, return all the posted data
(this is the normal type of message you receive from a browser. i.e. get me this page/image/thing..).
To get started you will need to install the mongoDB server.
There are very good step-by-step tutorials for all major platforms on the mongoDB site. so once you Install MongoDB. Fire it up to make sure everything is working fine.
navigate to wear the mongoDB executable is
cd /mongodb/bin |
Now start you mongoDB server *By default, MongoDB stores data in the /data/db directory.
mongod |
Output
Thu Aug 15 13:21:05.023 [initandlisten] MongoDB starting : pid=7444 port=27017 dbpath=\data\db\ 64-bit host=blackbolt Thu Aug 15 13:21:05.025 [initandlisten] db version v2.4.4 Thu Aug 15 13:21:05.025 [initandlisten] git version: 4ec1fb96702c9d4c57b1e06dd34eb73a16e407d2 Thu Aug 15 13:21:05.026 [initandlisten] build info: windows sys.getwindowsversion(major=6, minor=1, build=7601, platform=2, service_pack='Service Pack 1') BOOST_LIB_VERSION=1_49 Thu Aug 15 13:21:05.027 [initandlisten] allocator: system Thu Aug 15 13:21:05.028 [initandlisten] options: {} Thu Aug 15 13:21:05.079 [initandlisten] journal dir=\data\db\journal Thu Aug 15 13:21:05.081 [initandlisten] recover begin Thu Aug 15 13:21:05.082 [initandlisten] recover lsn: 15263608 Thu Aug 15 13:21:05.083 [initandlisten] recover \data\db\journal\j._0 Thu Aug 15 13:21:05.085 [initandlisten] recover skipping application of section seq:0 < lsn:15263608 Thu Aug 15 13:21:05.086 [initandlisten] recover skipping application of section more... Thu Aug 15 13:21:05.164 [initandlisten] recover cleaning up Thu Aug 15 13:21:05.165 [initandlisten] removeJournalFiles Thu Aug 15 13:21:05.167 [initandlisten] recover done Thu Aug 15 13:21:05.332 [initandlisten] waiting for connections on port 27017 Thu Aug 15 13:21:05.332 [websvr] admin web console waiting for connections on port 28017 |
We can now just leave this running.
Now in a new terminal window we install the mongoDB driver for Node.js
npm install mongodb |
So here we are going to have 2 files "server.coffee" and "mongo.coffee"
File: mongo.coffee
Here we have our class and the constructor. The constructors doing two things
- The 'response' being passed in is prefixed with '@' so it automatically becomes an attribute of the class.
- Creating our mongoDB connection
class myMongo constructor: (@response)-> databaseUrl = "mydb" collections = ["randomValues"] @db = require("mongojs").connect(databaseUrl, collections)
Here we create the save function that is used for the post messages.
It's split into two functions, so "save" initiates the writing to database and "_saveCallBack" after the values have been stored.
*note: there 'saveCallBack' function starts with an underscore. This is to denote that the function is private
save: (args) => @db.randomValues.save(args, @_saveCallBack) _saveCallBack: (err, saved) => if err? console.log(err) @response.write(err) else console.log("Saved #{JSON.stringify(saved)}") @response.write("will be saved") @response.end()
Here is a similar setup to "save" in that it has two functions but of course we are reading out the information that has been stored by the POST messages. You should know that line 13 is where the magic happens as it loops thru the return values outputting each on a new line("\n")
find: => @db.randomValues.find {}, @_findCallBack _findCallBack: (err, values) => console.log "#{values.length} Requested" if err? console.log err else if values.length is 0 @response.write "No values found" else @response.write JSON.stringify(val)+"\n" for val in values @response.end()
Finally we use "export" to allow our mongoDB manager class to be used with other files.
module.exports = myMongo
File: server.coffee
Very simple to start off. I'm bringing in the HTTP module and the mongoDB source that will handle the reading and writing of our values.
http = require "http" myMongo = require "./mongo"
Here's our request functional that will be run every time there is a connection is made.
There are four main thing happening here
- Set our HTTP header
- Created an instance of our mongoDB manager (mongo.coffee)
- Check if it a POST message and pass the values to be saved
- Else if it's a GET message and get the mongoDB manager to return all stored values
onRequest = (request, response) -> response.writeHead 200, "Content-Type": "text/plain" #pass in the 'response' object, so the mongoDB manager #can use it to output the values on a GET mongoConnet = new myMongo(response) if(request.method is 'POST') body = ''; request.on 'data', (data) -> body += data request.on 'end', () -> POST = JSON.parse (body) mongoConnet.save(POST) else if(request.method is 'GET') mongoConnet.find()
Here is where we build our server. you can see we're passing in the "onRequest" function and listening on PORT:8888.
O, and a little message to let us know our server is up and running.
server = http.createServer() server.on("request", onRequest) server.listen(8888) console.log "Server up and Ready to eat"
Now here comes two commands and you can run them in any order and see what you get. :D
This first one is the POST message that will store information into our database.
curl -i -X POST -H "Content-Type: application/json" -d '{"name":"brian","code":"sandwich"}' localhost:8888 |
Next we have the GET message that will retrieve our stored values.
curl -i localhost:8888 |
a copy of both source files is available on: GITHUB