Creating a REST API using Node.js, Express, and MongoDB

I recently used Node.js, Express, and MongoDB to rewrite a RESTful API I had previously written in Java and PHP with MySQL (Java version, PHP version), and I thought I’d share the experience…

Here is a quick guide showing how to build a RESTful API using Node.js, Express, and MongoDB.

Installing Node.js

  1. Go to, and click the Install button.
  2. Run the installer that you just downloaded. When the installer completes, a message indicates that Node was installed at /usr/local/bin/node and npm was installed at /usr/local/bin/npm.

At this point node.js is ready to use. Let’s implement the webserver application from the home page. We will use it as a starting point for our project: a RESTful API to access data (retrieve, create, update, delete) in a wine cellar database.

  1. Create a folder named nodecellar anywhere on your file system.
  2. In the wincellar folder, create a file named server.js.
  3. Code server.js as follows:

We are now ready to start the server and test the application:

  1. To start the server, open a shell, cd to your nodecellar directory, and start your server as follows:

    node server.js

  2. To test the application, open a browser and access http://localhost:3000.

Installing Express

Express is a lightweight node.js web application framework. It provides the basic HTTP infrastructure that makes it easy to create REST APIs.

To install Express in the nodecellar application:

  1. In the nodecellar folder, create a file named package.json defined as follows:

  2. Open a shell, cd to the nodecellar directory, and execute the following command to install the express module.

    npm install

    A node_modules folder is created in the nodecellar folder, and the Express module is installed in a subfolder of node_modules.

Now that Express is installed, we can stub a basic REST API for the nodecellar application:

  1. Open server.js and replace its content as follows:

  2. Stop (CTRL+C) and restart the server:

    node server

  3. To test the API, open a browser and access the following URLs:
    Get all the wines in the database: http://localhost:3000/wines
    Get wine with a specific id (for example: 1): http://localhost:3000/wines/1

Using Node.js Modules

In a large application, things could easily get out of control if we keep adding code to a single JavaScript file (server.js). Let’s move the wine-related code in a wines module that we then declare as a dependency in server.js.

  1. In the nodecellar folder, create a subfolder called routes.
  2. In the routes folder create a file named wines.js and defined as follows:

  3. Modify server.js as follows to delegate the routes implementation to the wines module:

  4. Restart the server and test the APIs:
    Get all the wines in the database: http://localhost:3000/wines
    Get wine with a specific id (for example: 1): http://localhost:3000/wines/1

The next step is to replace the placeholder data with actual data from a MongoDB database.

Installing MongoDB

To install MongoDB on your specific platform, refer to the MongoDB QuickStart. Here are some quick steps to install MongoDB on a Mac:

  1. Open a terminal window and type the following command to download the latest release:

    curl > ~/Downloads/mongo.tgz

    Note: You may need to adjust the version number. 2.2.0 is the latest production version at the time of this writing.

  2. Extract the files from the mongo.tgz archive:

    cd ~/Downloads
    tar -zxvf mongo.tgz

  3. Move the mongo folder to /usr/local (or another folder according to your personal preferences):

    sudo mv -n mongodb-osx-x86_64-2.2.0/ /usr/local/

  4. (Optional) Create a symbolic link to make it easier to access:

    sudo ln -s /usr/local/mongodb-osx-x86_64-2.2.0 /usr/local/mongodb

  5. Create a folder for MongoDB’s data and set the appropriate permissions:

    sudo mkdir -p /data/db
    sudo chown `id -u` /data/db

  6. Start mongodb

    cd /usr/local/mongodb

  7. You can also open the MongoDB Interactive Shell in another terminal window to interact with your database using a command line interface.

    cd /usr/local/mongodb

    Refer to the MongoDB Interactive Shell documentation for more information.

Installing the MongoDB Driver for Node.js

There are different solutions offering different levels of abstraction to access MongoDB from Node.js (For example, Mongoose and Mongolia). A comparaison of these solutions is beyond the scope of this article. In this, guide we use the native Node.js driver.

To install the the native Node.js driver, open a terminal window, cd to your nodecellar folder, and execute the following command:

npm install mongodb

Implementing the REST API

The full REST API for the nodecellar application consists of the following methods:

Method URL Action
GET /wines Retrieve all wines
GET /wines/5069b47aa892630aae000001 Retrieve the wine with the specified _id
POST /wines Add a new wine
PUT /wines/5069b47aa892630aae000001 Update wine with the specified _id
DELETE /wines/5069b47aa892630aae000001 Delete the wine with the specified _id

To implement all the routes required by the API, modify server.js as follows:

To provide the data access logic for each route, modify wines.js as follows:

Restart the server to test the API.

Testing the API using cURL

If you want to test your API before using it in a client application, you can invoke your REST services straight from a browser address bar. For example, you could try:

You will only be able to test your GET services that way. A more versatile solution to test RESTful services is to use cURL, a command line utility for transferring data with URL syntax.

For example, using cURL, you can test the Wine Cellar API with the following commands:

  • Get all wines:

    curl -i -X GET http://localhost:3000/wines

  • Get wine with _id value of 5069b47aa892630aae000007 (use a value that exists in your database):

    curl -i -X GET http://localhost:3000/wines/5069b47aa892630aae000007

  • Delete wine with _id value of 5069b47aa892630aae000007:

    curl -i -X DELETE http://localhost:3000/wines/5069b47aa892630aae000007

  • Add a new wine:

    curl -i -X POST -H 'Content-Type: application/json' -d '{"name": "New Wine", "year": "2009"}' http://localhost:3000/wines

  • Modify wine with _id value of 5069b47aa892630aae000007:

    curl -i -X PUT -H 'Content-Type: application/json' -d '{"name": "New Wine", "year": "2010"}' http://localhost:3000/wines/5069b47aa892630aae000007

Next Steps

In my next post, I’ll share a client application that makes use of that API. Update: The “next post” is now available here.

160 Responses to Creating a REST API using Node.js, Express, and MongoDB

  1. Phil October 2, 2012 at 6:40 pm #

    This is sweet! Thanks!

    • Ralph Allan Rice November 26, 2012 at 6:15 pm #

      Good tutorial!

      One minor note: even though you do not explicitly mention the content type, the examples at the beginning do not output (strictly) legal JSON. The keys for id, name and description should be quoted.


      2.2. Objects

      An object structure is represented as a pair of curly brackets
      surrounding zero or more name/value pairs (or members). A name is a
      string. A single colon comes after each name, separating the name
      from the value. A single comma separates a value from a following
      name. The names within an object SHOULD be unique.

      object = begin-object [ member *( value-separator member ) ]

      member = string name-separator value

      • Ralph Allan Rice November 26, 2012 at 6:33 pm #

        I didn’t notice my previous comment was not complete. I wanted to end it with this question:

        Does Response#send() properly format to json? According to the docs, it just says that it will respond with a JSON representation.

        • wprl July 12, 2013 at 9:57 am #

          I think what you’re looking for is res.json

    • Jeff February 6, 2013 at 6:45 pm #

      Mongo has released a new Class MongoClient (announced a month after this article).

      From driver version 1.2 we are introduction a new connection Class that has the same name across all out official drivers. This is to ensure that we present a recognizable front for all our API’s. This does not mean you existing application will break but that we encourage you to use the new connection api to simplify your application development.

  2. Jon October 2, 2012 at 7:00 pm #

    Good example of a CRUD api, but unfortunately not a REST api. Research HATEOAS to understand why.

    • Chris December 11, 2012 at 2:28 pm #

      Would perhaps be a more constructive comment if it outlined what would make it a full REST api. As I understand things the important thing missing is that e.g. after a POST added a new wine the response would include the URI to GET that wine entity. ?

      • F Galloway February 6, 2013 at 6:21 pm #

        Thank you for your post, it was helpful. A REST API without returning Hypermedia (HTML5 links/forms or the specific JSON/XML media-type representation) is not truly RESTful. An API that returns Hypermedia allows the itself to evolve independently without breaking the client. The client only needs to know the initial URI of the API and has a basic understanding of the API’s semantics. It is very similar to how a person uses a website, by going to a specific domain, recognizing the navigation options(links) and/or state transitions(forms) and interacting with them.

        After reading “Building Hypermedia APIs with HTML5 and Node” I think HTML5 as a data-interchange format is really quite interesting and has a lot of potential to simplify data presentation for front-end engineers. Too bad node.js does not have a native event-based HTML5 Parser (it does for JSON, why not HTML5?)

        • wprl July 12, 2013 at 9:56 am #

          Hypermedia !== HTML though. E.g. JSON + Link header meets the criteria for discoverability.

      • F Galloway February 6, 2013 at 6:24 pm #

        A nice summary

    • Olivier January 10, 2013 at 1:23 pm #

      That comment does not help in any way. If you *think* you understand REST better than anyone else, then explain what you find sub-optimal in the proposed solution and propose concrete improvements. Otherwise, you are only making noise around a very nice and helpful blog (thanks a lot for that Chris).

  3. J Bunting October 2, 2012 at 10:14 pm #

    Thanks for posting this Chris, super useful.

  4. October 3, 2012 at 10:42 pm # super useful for posting this Thanks

  5. Ihor October 3, 2012 at 11:16 pm #

    good post. Thanks.
    Few questions:
    1. sessions – how to block any hacks with DELETE and PUT any records
    2. Big DB – what about speed with a lot of records like 100k or more in each table
    3. FileAPI – I mean upload/download

    • T Horton December 8, 2013 at 10:11 am #

      Did you ever get a good follow up on this?

      I’m mostly just interested in how people are handling spam PUT/DELETE requests. Generate a token based on the session somehow and match it server side? I’d rather not figure out my own janky method if someone else has already ‘solved’ it.

  6. lemeteore October 4, 2012 at 1:55 am #

    Thanks a lot, really nice indeed. But I think we should read this one:

    • demirdöküm kombi servisi September 6, 2013 at 12:46 pm #

      What do you mean “We are preparing an update.”? Does that mean you are going to put the server check back in? If so, that’s a shame.

  7. October 4, 2012 at 7:53 pm #

    posts is a good

  8. Chun October 4, 2012 at 7:58 pm #

    Has anyone tested the curl commandes for Add a new wine and Modify wine with _id value ?
    Theu return errors for me.

    • duynii November 17, 2012 at 10:11 am #

      I am completely new to this, have to do uni project.

      Problem is req.body is undefined.

      After searching express, I see that you must use parseBody() middleware, I guess the default is it parses the URL.

      // You need this at top of server.js

  9. Ken McGelt October 7, 2012 at 11:42 pm #

    Pretty good so far, but where is this defined?

    • Chuck January 15, 2013 at 9:28 pm #


      It would be kept under two placesL

      1. under ./server.js – where routes are defined / associated with corresponding methods.
      2. under ./routes/wines.js – the method code is actually defined.

      As you can see under 1. No “search” function exists – it would be pretty easy to just add one under 1 & 2… Currently you can only find by “id”. by using “http://localhost:3000/wines/id” – replace id with the actual id in the db.

  10. Jeff October 8, 2012 at 5:26 am #

    Deployd is another node framework that uses MongoDB to make JSON APIs, a little more narrowly focused than express:
    npm install deployd

  11. David Noleto(Brazil) October 9, 2012 at 6:55 pm #

    when you make an example with Sencha Touch 2 and PhoneGap ?

    • Chuck January 15, 2013 at 9:30 pm #


      Don’t hold your breath – Chris works for Adobe which competes with Sencha Touch via Phone Gap….

      Not that I like Sencha more than Phone Gap – just stating facts.

  12. Greeshma October 10, 2012 at 11:54 pm #

    Hi All,
    I am an University student and unable to install mongodb 2.2.0,whenever i write the command
    md C:\mongodb\log,it throws out syntax error -missing ; before statement (shell):1.same error i got while i tried installing 2.0.7,Please help me knowing how to correct it.

  13. Carlos Saraiva October 12, 2012 at 1:30 am #

    You say: “In my next post, I’ll share a client application that makes use of that API. Update: The “next post” is now available here.” But the link points back to this page. Please help!!!!!

  14. Christophe October 12, 2012 at 8:08 pm #

    @Carlos: sorry. I just fixed the link.

  15. Ben October 16, 2012 at 11:55 pm #

    Don;t forget to start Mongo cd /usr/local/mongodb
    ./bin/mongod before testing REST services straight from a browser address bar

  16. heri October 27, 2012 at 6:06 pm #

    Thank you, this is great

  17. neutron October 28, 2012 at 8:33 am #

    Thanks this was a great tutorial, very easy to follow along and to the point.

  18. neutron October 29, 2012 at 5:27 am #

    When using this if there isn’t a valid _id record it throws an error like so:

    Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters

    I want this to return an error code.

    I notice that it does this also in your live version

    Is there an easily way to fix this ? I am new to node and mongodb (this tutorial helped me get setup see post above). I read else where that could use async or fnqueue to fix this but I haven’t be able to do so.

  19. kobra November 12, 2012 at 9:59 pm #

    what about securing the api with authentication system?

  20. Roberto November 21, 2012 at 4:17 pm #

    that’s sweet!

    but actually with this implementation of…)

    you’re not going to create any collection (to populate)

    - db.collection(‘wines’, {safe:true}, function(err, collection) {


    + db.createCollection(‘wines’, {safe:true}, function(err, collection) {



    though as stated on the node.js driver docs, db.collection(…) doesn’t have “safe” as an option, then no errors can go back to the callback.

    • Kyle Buchanan January 15, 2013 at 10:24 pm #

      I ended up having to do the following:

      db.createCollection(“wines”, {strict : true}, function(err, collection) {
      if (!err) {

      • Joe January 20, 2013 at 5:58 am #

        Great post, Christophe! Thank you!

        Kyle: everything worked for me, except the populating of the db. Your fix here (replacing safe with strict) got it working. Thanks!

  21. Roberto November 21, 2012 at 4:34 pm #

    well i was wrong :)

    “If strict mode is off, then a new collection is created if not already present.”

    though it doesn’t work for me… strict mode is off by default, right? :(

  22. ahmad November 22, 2012 at 4:26 am #

    Hi Chris,

    Have you ever had an issue with db.collection and db.createCollection?
    I see how you used “safe:true” as a parameter to check if the collection exists.

    I copied your code exactly and put it on a brand new aws instance. Everything seems to work great except when calling “db.collection”, err is always null so “populateDB()” is never called.

    Tried switching it to db.createCollection and same problem – err is always null so populateDB is called EVERY time.

    Tried searching around for this problem but couldn’t find much… any ideas?

    Thanks for the great tutorial!, db) {
    if(!err) {
    console.log(“Connected to ‘winedb’ database”);
    db.createCollection(‘wines’, {safe:true}, function(err, collection){
    if (!err){
    console.log(“The ‘wines’ collection doesn’t exist. Creating it with sample data…”);
    } else {
    console.log(‘wines collection exists’);
    db.collection(‘wines’, {safe:true}, function(err, collection) {
    if (err) {
    console.log(“The ‘wines’ collection doesn’t exist. Creating it with sample data…”);
    } else {
    console.log(‘wines collection exists’);

    • ahmad November 25, 2012 at 4:52 am #

      Still not sure why the db.collection and db.createCollection features are not working the way they’re supposed to. Maybe the module needs to be updated for the latest version of node?

      Anyway, I found a workaround…

      db.collection(‘wines’, function(err, collection){
      collection.findOne(function(err, item) {
      if (!item){

      • Chun November 30, 2012 at 8:46 am #

        I confirm that db.collection doesn’t work if you do npm install mongodb these days.

        db.collection worked when I did npm install mongodb on october, 11.

        If I do npm install mongodb right now and compare with windiff on the directories “node_modules\mongodb” of today and “node_modules\mongodb” of october, 11, there are 7 differences, among these, there are new files : mongo_client.js, base.js and url_parser.js.

        I can’t explain why yet.

        • Siegfried Bolz March 25, 2013 at 6:08 pm #

          My solution:

, db) {
          if(!err) {
          console.log(“Connected to ‘winedb’ database”);
          db.createCollection(‘wines’, {strict:true}, function(err, collection) {
          if (err) {
          console.log(“The ‘wines’ collection doesn’t exist. Creating it with sample data…”);

    • Chuck January 15, 2013 at 8:19 pm #

      I’m getting the exact same error… Wish I knew how to get around it !

  23. tektaş pırlanta yüzük November 24, 2012 at 1:29 am #

    Thanks this is the best.i hope you will continue this topic.

  24. Luka December 10, 2012 at 10:21 am #

    Man, you really know how to blog… I love your patient and detailed way of writing… You would be a great teacher :) well, you are… Thanks…

  25. Blacar December 10, 2012 at 12:50 pm #

    Can’t see any code in the post :P

  26. BigKev December 14, 2012 at 7:33 am #

    Hi – I have converted your code for use with MySQL. I have everything working fine but one problem which involves var id = I can display id on the web page but when I try to use as an input to an SQL statement I continually get an undefined issue. Is this a string issue or a MySQL issue?
    Any thoughts would be much appreciated.

  27. Hamilton Teixeira December 16, 2012 at 5:24 am #

    Great tuto…but at line 12 on wine.js is missing {safe: true} as param to complete run the app.

    On your git is updated..

    Anyway…thanks…save me a lot of time… i’m implement this on my project.

  28. jorawebdev December 17, 2012 at 9:34 pm #

    Great resource Chris! An empty array is being returned on one of my set ups instances, however.

    Here’s what I’m getting:

    Listening on port 3000…
    Connected to ‘winedb’ database
    Retrieving wine: undefined

    Mongo’s running w/o problems. But I see this:
    “recover : no journal files present, no recovery needed”. Can anyone shine some light on the issue?

    • thfabric December 31, 2012 at 1:48 pm #

      @jorawebdev I guess with latest release of mongodb, it doesn’t produce an error when browsing an non existent collection. In wines.js, change line 14 from “if (err) {” to “if (!err) {” and the db will be populated once you point your browser to http://localhost:3000/wines. Don’t forget to comment this line afterwards.

      Hope it helps,

      • Jay March 19, 2013 at 11:08 am #

        The way I went about is was as follows:

        created a checkseed.json file with the following content: {“seed_db”:true}.

        Then in my ./routes/wines.js file, I have added the following method:

        var checkDBSeeding = function() {
        var fs = require(‘fs’);
        fs.readFile(‘./checkseed.json’, ‘utf8′, function(err, data) {
        if(err) {

        try {
        obj = JSON.parse(data);
        if(obj.seed_db) {
        console.log(“The ‘wines’ collection does not exist. Creating it with sample data…”);

        // then we need to mark this as done
        obj.seed_db = false;
        jsonData = JSON.stringify(obj);
        fs.writeFile(‘./checkseed.json’, jsonData, function(err) {
        if(err) {
        console.log(“There has been an error saving your configuration data.”);
        } catch(err) {
        console.log(“There has been an error parsing your JSON”);

        I left populateDB() as per the tutorial, so no changes there.

        And in the method (still in ./routes/wines.js), I have replaced it as follows:, db) {
        if(!err) {
        console.log(“Connected to ‘winedb’ database”);
        db.collection(‘wines’, function(err, collection) {

        Hope it helps. :-)

  29. sohbet odalari December 20, 2012 at 6:35 pm #

    very blog thanks

  30. kelebek indir December 20, 2012 at 6:36 pm #

    very thanks

  31. TdManson January 9, 2013 at 3:01 am #

    when trying this, and executing this curl :
    curl -i -X GET http://localhost:3000/wines/5069b47aa892630aae000007

    I get this response :

    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Length: 0
    Date: Wed, 09 Jan 2013 02:59:59 GMT
    Connection: keep-alive

    server screen show this :
    Listening on port 3000…
    Connected to ‘winedb’ database
    Retrieving wine: 5069b47aa892630aae000007
    GET /wines/5069b47aa892630aae000007 200 3ms – 0

    Now I am a noob, but shouldn’t I be seeing some useable output? not just something that looks like a debug session info !!

    Thanks for the tutorial though, awsome.

    • Almoral January 18, 2013 at 5:01 pm #


      I don’t know if you found a solution already but I was having the same issue. My problem was caused by the issue that @Ahmad mentioned in his reply. Basically the db is created but not populated. I commented out the error check, “if(err)” in the function and let the populateDB() method run. Then I just uncommented it so it didn’t run every time.

  32. Tanmay January 18, 2013 at 12:31 pm #

    Thank you very very very much……This tutorial is best. Thank you… I hope you will continue….

  33. Chandra January 18, 2013 at 9:17 pm #

    Excellant tutorial!
    What additions to server.js I need to make, in order to also serve static HTML/CSS/JS files?

  34. Willem January 19, 2013 at 6:20 pm #

    GREAT post! Thanks a lot. This is awesome for someone like me who is getting into Node for the first time.

  35. techfuser January 25, 2013 at 3:50 pm #

    @coenraets, plz help me understand the following 2 lines:



  36. Bob Chesley January 26, 2013 at 9:09 pm #

    Hi Chris,

    Thanks for putting this together. It’s always hard getting started with cutting edge technologies like these but your approach of a full application really helped me get up to speed quickly.



  37. daniel January 28, 2013 at 11:25 pm #

    I met php two months and a half months ago, I´ve dedicated myself everyday.
    But meeting Node.js and Express.js and MongoDB not more than a week ago has totally shifted some concepts.

    I will follow your guide thoroughly after work.( If I can ) else ( back to basics )
    Thanks so much for this guide!!

  38. securedeveloper January 29, 2013 at 5:12 am #

    so just curious if anyone else did the post using curl and ran into a situation where the content of the post did not populate the database correctly? (i tweaked the fields so users == wines and i keep different data entries than wines but other wise same code) For example i used curl:

    curl.exe -i -X POST -H ‘Content-Type: application/json’ -d ‘{“name”:”Joe Shmoe”,”bestpos”:”forward”,”posrating”:10,”notes”:”look out for this guy”}’

    when i access the data at the /users (findALL) url i get:
    "name": "David Beckham",
    "bestpos": "forward",
    "posrating": "7",
    "notes": "needs to work on focus on game instead of being a celebrity, make him run laps.",
    "_id": "51074fa54741f7c410000001"
    "name": "Cristiano Ronaldo",
    "bestpos": "forward",
    "posrating": "10",
    "notes": "Keeps smiling at cameras instead of focusing at practice, make him run with Beckham.",
    "_id": "51074fa54741f7c410000002"
    "name": "Zinedine Zidane",
    "bestpos": "forward",
    "posrating": "9",
    "notes": "Does a great job and never gives any problems at practice.",
    "_id": "51074fa54741f7c410000003"
    "'{name:Joe Shmoe,bestpos:forward,posrating:10,notes:look out for this guy}'": "",
    "_id": "510754aa81032f681b000001"

    note the last entry makes the entire set of items one item. Anyone else experience this?

    • securedeveloper January 29, 2013 at 5:24 am #

      Answered my own question. must have been a curl/windows command line thing. i created an html form page and posted that way and it worked without issue. Thanks for a great tut that totally got me started (peeled the first peel of the orange) with node.js.

  39. barksten February 13, 2013 at 8:32 pm #

    This tutorial was a perfect fit for me. I know I’m late to the node.js game but I just wanted to see some concrete example on how you could use node.js. This tutorial was exactly what I was looking for.
    Too bad I hit the same bug (doesn’t populate db) as everybody else that installed a newer mongoDB so I was forced to read all the comments.

  40. morefromalan February 14, 2013 at 5:23 am #

    I think this is a great post and I feel the need to defend it from the REST detractors.

    The point here is /not/ how to make the most RESTful REST api. The point is to boil down express (primarily), node and mongo (secondarily) into a good set of ‘courseware’. I’ve hired trainers for products I’ve managed, and the best break their lessons down exactly like this post does: into a set of bite sized successes that focus on the core principals.

    A REST api is a good piece of subject matter IMHO because it
    a) keeps the lesson simple but practical
    b) nudges readers towards application designs that work well with node

    If you want a really great REST API, write one. If you want security, put it behind a reverse proxy or read one of the umpteen articles on OAUTH etc.

    Node and express are great and really rewarding to develop in, but their docs are not (yet) fabulous. This post plays a helpful role in the node dev community.

  41. Chris February 14, 2013 at 8:04 pm #

    Super-useful, thanks a lot!

  42. fitted bedrooms February 15, 2013 at 12:43 pm #

    I think everything posted was very reasonable. However, consider this, what
    if you added a little content? I am not suggesting your information isn’t good., but suppose you added a post title to maybe grab folk’s attention?
    I mean Creating a REST API using Node.js, Express,
    and MongoDB | Christophe Coenraets is a little plain.
    You could peek at Yahoo’s home page and note how they create article titles to grab people interested. You might add a video or a related picture or two to get people excited about what you’ve got to
    say. In my opinion, it could bring your posts
    a little livelier.

  43. Geoffrey Cox February 22, 2013 at 5:18 am #

    Excellent tutorial!

  44. Evelyn March 1, 2013 at 9:29 pm #

    This helped me get started with mongo and node.js, thank you!

  45. Hire A Vibration Plate March 4, 2013 at 12:44 am #

    Excellent post. I used to be checking constantly this weblog and I’m inspired! Extremely helpful info particularly the ultimate section :) I maintain such info a lot. I used to be seeking this particular information for a very lengthy time. Thanks and best of luck.

  46. Fastidious respond in return of this issue with real arguments and explaining the
    whole thing on the topic of that.

  47. visit this March 5, 2013 at 8:34 pm #

    Good day very cool site!! Guy .. Beautiful .. Wonderful .. I’ll bookmark your website and take the feeds also?I’m glad to seek out a lot of useful information here within the post, we need develop extra techniques on this regard, thanks for sharing. . . . . .

  48. agnes March 13, 2013 at 7:21 am #

    Good tutorial. I’m a beginner and it really helped me a lot.
    I need to write queries in the uri’s like return all wines with name ‘new year’. For this my uri should be like ‘http://localhost:3000/wines?name=newyear’ or my uri can also be ‘http://localhost:3000/wines?name=newyear&year=2010′ . Now, how can i write these queries in wines.js and get them appended to uri in server.js??? Please help me! I’ve been trying this from 2days. Thank you.

  49. Bob Miner March 13, 2013 at 10:09 pm #

    Excellent post. Thanks. Did you happen to do any performance testing to see how this new web service compares with your earlier Java web service?

  50. Nathaniel March 19, 2013 at 1:14 am #

    Dude, this is soooo cool! Thanks for doing this!!

  51. urfx April 2, 2013 at 11:51 pm #

    Hi Chris, I’ve used this tute a number of times. Very helpful thanks. Have you got an example of how to upload and image to this API ?

  52. Cesar Acuna April 3, 2013 at 7:14 am #

    Extremely useful and well prepared. Thanks a lot. Best of luck!

  53. Justin Goffinet April 7, 2013 at 7:36 am #

    Under the heading “Implementing the REST API” all I see is:

    To implement all the routes required by the API, modify server.js as follows:

    To provide the data access logic for each route, modify wines.js as follows:

    Restart the server to test the API.

    It seems like there’s a bit missing there. ;)

    p.s. Dev tools seems to think that 7 of your github gists are failing to load.

    Love your work! Keep at it.

  54. mytantine April 8, 2013 at 4:18 pm #

    Hello, thanks for this awesome tutorial! How is it possible to add date when we create a wine entry?

  55. Ab April 10, 2013 at 6:32 am #

    Your gists are missing. And that makes it a unusable tutorial.

    • Leandro April 13, 2013 at 10:20 pm #

      It happened to me too.
      Just refresh this page and you will be good to go!

  56. Leandro April 13, 2013 at 10:18 pm #

    3 steps, 3 functional examples, 1 functional app.
    Thank you so much for this article.

  57. Jack April 28, 2013 at 4:00 pm #

    This is great! Just one question though, how do I get UTF-8 support on this? (New at Node.js)

  58. Stephon Harris May 1, 2013 at 1:37 pm #

    Im getting an error when I type ‘node server.js’
    After updating server.js and wine.js during the Implementing the REST API section.

    Here’s a picture of the error –>
    The error says:

    throw er; // Unhandled ‘error’ event
    Error: listen EADDRINUSE
    at errnoException (net.js:884:11)
    at Server._listen2 (net.js:1022:14)
    at listen (net.js:1044:10)
    at Server.listen (net.js:1110:5)
    at (/Users/Stepharr/Workspaces/nodecellar/node_modules/express/lib/application.js:535:24)
    at Object. (/Users/Stepharr/Workspaces/nodecellar/server.js:30:5)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)

    • Ardi June 17, 2013 at 11:07 am #

      change the port.

  59. Paul May 5, 2013 at 2:15 pm #

    works great using _id but I tried using year as parameter to find result e.g. search on year
    but it doesnt seem to work
    any idea why

  60. Joel Smith May 11, 2013 at 10:45 am #

    Just a note that I wanted to add after working through this. Mongo has updated their native Node.js client, so you’ll have to change out some of your routes file. Namely:

    var Server = mongo.Server,
    Db = mongo.Db,
    BSON = mongo.BSONPure;
    var Server = mongo.Server,
    Db = mongo.Db,
    BSON = mongo.BSONPure;
    ObjectID = mongo.ObjectID;

    And for each time you would have used BSON.ObjectID, simply use ObjectID. Mongo seems to have decoupled them.

    This should make your findById method work properly now.

    • Joel Smith May 11, 2013 at 10:47 am #

      Sorry should be:

      var Server = mongo.Server,
      Db = mongo.Db,
      BSON = mongo.BSONPure,
      ObjectID = mongo.ObjectID;

      Accidentally left the semi-colon on there.

    • Zach May 20, 2013 at 1:34 am #

      Thanks Joel.. I will try that. I have everything working with nodecellar except populating the wine list from the URI, and i’m assuming this is the issue.

  61. Michael J. Ryan May 17, 2013 at 1:25 pm #

    Okay, I would suggest a slightly different approach to your wines route/module…

    in the wines.js

    module.exports.bind = function(app,base) {
    base = base || ‘/wines’;
    app.get(base, findAll);
    app.get(base + ‘/:id’, findById);, addWine);
    app.put(base + ‘/:id’, updateWine);
    app.delete(base + ‘/:id’, deleteWine);

    in your app.js

    wines.bind(app, ‘/wines’)


    Taking the above approach, you can isolate your modules, and be able to work on it separately, while allowing the flexibility to mount to a different base path for the module.

  62. Pete May 26, 2013 at 2:45 pm #

    In step 2, it says “In the wincellar folder,” but it should call the folder “nodecellar”.

    Also, it appears the code listing for server.js has disappeared?

  63. Ben June 3, 2013 at 5:46 pm #

    I have this output:

    curl: (6) Could not resolve host: application
    curl: (6) Could not resolve host: New Wine,
    curl: (6) Could not resolve host: year
    curl: (3) [globbing] unmatched close brace/bracket at pos 5
    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: application/json; charset=utf-8
    Content-Length: 19
    Date: Mon, 03 Jun 2013 21:42:02 GMT
    Connection: keep-alive

    “‘{name:”: “”

    I can use curl for the get and delete actions but not the put or post actions. I wondered if my default write concern in my mongodb is messed up. Thoughts?

    Thanks, Ben

    • Sean March 28, 2014 at 7:17 am #

      Bump, I also have this problem.

  64. internet site June 6, 2013 at 6:03 am #

    This is a topic that is near to my heart… Cheers! Exactly where
    are your contact details though?

  65. David June 6, 2013 at 9:48 pm #

    Great article. Got us up in running with our API in no time.

    • Alex June 27, 2013 at 12:42 pm #

      Hello, this article is great, but may be someone be able to help me with an application that runs on apache and needs to consume a rest service, I am doing this but does not work:

      $(document).ready(function() {
      type: “GET”,
      data: ‘{}’,
      contentType: “application/json; charset=utf-8″,
      url: “http://localhost:3000/wines/”,
      dataType: “jsonp”,
      processdata: true,
      success: function(data) {


  66. wprl July 12, 2013 at 9:59 am #

    Would be interesting to get your opinion on the baucis module http://github/wprl/baucis It provides abstractions for common situations when building a REST API with Node + Express + Mongo…

  67. July 17, 2013 at 5:14 am #

    Hi, I do think this is a great blog. I stumbledupon it ;)
    I may return once again since I book-marked it.
    Money and freedom is the greatest way to change, may you be rich and
    continue to guide other people.

  68. saran July 18, 2013 at 8:00 am #

    Good blog. Thanks a lot…

  69. dragon city cheat July 19, 2013 at 2:55 am #

    If you love seeing complements you’ll have fun with this, since designers of the video game paid a lot of attention to information. Suits could be saw not simply inside second but with three dimensional. Enjoying matches can help you with all the operations in the team and also total improvement. It possibly contains fits previously played. The surroundings on the activity is perfectly made with text and also reasonable animation. This position of the workforce might be improved by means of investing in a Top quality Package deal, which often will provide you with a benefit over your current competitors.

    Articles on the top quality type: – double some time of an match up — visualization in the go with (from 6 to help 12 minutes) — enjoy warm and friendly video games along with various other professionals – change your own club-˜s logo – select the players-˜ equipmnet — there isn’t any bill deactivation (you may stay logged out and about regarding 21 nights plus your golf club will not be removed
    from you) -build some sort of stadium with increased capability nearly 25 000 car seats -bonus connected with one
    hundred fifty credits

    Standing: ICESHOOT delivers a terrific knowledge on earth associated with on
    the internet gaming. Very easy lag guiding some other globe chief managers.

  70. Ken July 27, 2013 at 3:30 am #

    All of the github code snippets are 404 :/

  71. Praveena August 9, 2013 at 8:01 am #

    Thanks a lot for this post.

  72. best clash clans August 9, 2013 at 10:06 am #

    Engage in around two hundred entertaining ranges throughout Tale, Puzzle, along with Countless tactic while locating
    the particular thieved artifacts in addition to demanding minions on the serious.
    Delight in excellent computer game titles, relieve special power-ups, along with earn masterful triumphs.

    PC Activity : Adelantado Trilogy: Guide A single

    Carry out you love to discover the actual amazing strategies from the rainforest in which cover in Adelantado Trilogy: Guide best clash clans One?
    Uncover as well as sodium absent your missing trip together with Put on Diego De Leon, the actual brave and noble police officer.
    To understand with the local people who is going
    to always be associated with be an aid to an individual.

    Assist your natives bring back their particular complexes, collect food items,
    and build a arrangement. Boost your own expertise to get the many items along with achieve splendid trophies with this demanding computer game.

    Love this particular enjoyable Method sport by sensation that you usually are between
    the very first to set ft . in Adelantado. Your search most likely are not easy since you could have more pleasurable exploring your
    isle and overlook you are into it for the motive.
    The Spanish-inspired soundtrack will always make you sense the particular is is actually yours.
    Set your selected problem configurations which range from tranquil in order to
    tricky, in addition to ten vast road directions to

    You’ll be given a benefit chart if you possibly could full other levels which has a rare metal score. Don’t forget in order to save the
    misplaced dispatch and have enjoyment value searching!

    These kinds of exciting computer system games will really concern anyone and give an individual exciting concurrently!

    Read more critiques and also details about acquire video game titles for your computer pay
    a visit to: My own Free download Game titles

    Linked Content — computer games, ps online games assessment,
    online games evaluation, online games on the web, acquire online games,
    get online games online, cost-free on-line
    computer games, download free online games,

    Email this short article to your Close friend!

    Receive Content articles such as this one one on one for
    your mail package! Register without cost right now!

  73. Jason August 30, 2013 at 3:25 am #

    I’m having trouble getting my server started…

    I made some changes, hoping, I can run two routes for two different sections of the application…

    var express = require(‘express’),
    path = require(‘path’),
    http = require(‘http’),
    spirit = require(‘./routes/spirits’),
    wine = require(‘./routes/wines’);

    var app = express();

    app.configure(function () {
    app.set(‘port’, process.env.PORT || 3000);
    app.use(express.logger(‘dev’)); /* ‘default’, ‘short’, ‘tiny’, ‘dev’ */
    app.use(express.static(path.join(__dirname, ‘public’)));

    app.get(‘/wines’, wine.findAll);
    app.get(‘/wines/:id’, wine.findById);‘/wines’, wine.addWine);
    app.put(‘/wines/:id’, wine.updateWine);
    app.delete(‘/wines/:id’, wine.deleteWine);

    app.get(‘/spirits’, spirit.findAll);
    app.get(‘/spirits/:id’, spirit.findById);‘/spirits’, spirit.addSpirit);
    app.put(‘/spirits/:id’, spirit.updateSpirit);
    app.delete(‘/spirits/:id’, spirit.deleteSpirit);

    http.createServer(app).listen(app.get(‘port’), function () {
    console.log(“Express server listening on port ” + app.get(‘port’));

    but I get the error :

    Error: .post() requires callback functions but got a [object Undefined]

    - I’m new to express… can someone help me out? What am I doing wrong?

    • Nilesh February 6, 2014 at 7:39 pm #

      I had a similar error. ‘requires callback functions’ error means the its not possible to execute the callback function. Actually I had ‘{‘ missing for one of the function(req,res). After fixing that, error went away and everything just worked fine.

      Great article Christophe. Thank you so much

  74. Dmitri August 31, 2013 at 10:39 pm #

    You say “Code server.js as follows:” and then there is nothing, please fix.

    • Dmitri August 31, 2013 at 10:41 pm #

      Sorry, now I can see the code… it wasn’t showing before. Please ignore my last comment.

  75. Dom September 3, 2013 at 7:03 pm #

    Very useful guide, thank you.
    I don’t know if you are aware Christophe but your pieces of code don’t show up within my Chrome browser, they do appear in Firefox however.
    I don’t know if that’s something specific on my end or on your end.


  76. seiko 速報 September 5, 2013 at 1:41 am #

    seiko レディース

  77. Newbee September 6, 2013 at 10:58 am #

    Thank you for this post. I am following it step by step but running into an error.

    Step 3 in the using node JS module has a snippet of cade that says:

    wines = require(‘./routes/wines’);

    This command fails in a Windows environment….I have tried all possible variations but it fails to bring up the server:


    The code errors at this row saying that it cannot find the module ‘./routes/wines’.
    Help !

  78. Steve Cochrane September 19, 2013 at 1:08 am #

    I just wanted to say this guide is fantastic, and with it I had my first API (and first back-end application) running within an hour. Thanks so much!

  79. site de rencontre September 22, 2013 at 1:12 am #

    We’re a group of volunteers and starting a new
    scheme in our community. Your site provided us with useful information to work on.
    You’ve performed a formidable job and our whole group shall be
    thankful to you.

  80. September 23, 2013 at 1:26 pm #

    Out of all the people around you who are quite overweight,
    what percentage of them do you think are eating out of an addiction or mental need for
    food, rather than mere gluttony. However, if this is how you describe your goal, then
    you will find it hard to achieve because it does not focus on the positive or anything tangible.
    In 1993, the movie Groundhog Day, starring Bill Murray, brought worldwide attention to this most-watched
    weather forecast day led by a rodent.

  81. laser dentistry September 27, 2013 at 4:39 pm #

    Each day is really a brand-new day to focus on dropping pounds as well as staying healthy and this web site has presented me a strategy to remain focused and
    I am making great advances to attaining my ultimate physique.
    Thank you for everything.

  82. September 28, 2013 at 7:09 pm #

    Attractive section of content. I just stumbled
    upon your blog and in accession capital to assert that I get actually enjoyed account your
    blog posts. Anyway I’ll be subscribing to your feeds and even I achievement you
    access consistently rapidly.

  83. belysning led October 17, 2013 at 7:55 pm #

    I every time emailed this webpage post page to all my associates, for the reason that if like to read it next my
    friends will too.

  84. comment tricher sur candy crush saga October 18, 2013 at 6:31 pm #

    After I originally commented I appear to have clicked the -Notify me when new comments are added- checkbox and from now on
    each time a comment is added I recieve four emails with the
    same comment. There has to be an easy method you can
    remove me from that service? Cheers!

  85. Horror Games Free Download November 11, 2013 at 6:01 am #

    Greetings! Very useful advice in this particular
    post! It’s the little changes which will make
    the most important changes. Many thanks for sharing!

  86. Ivan November 29, 2013 at 9:18 am #

    Merci, c un super boulot !

  87. Chris December 6, 2013 at 3:36 pm #

    Is it possible or better to have the app.js do the connection to the database, then pass that connection to the wines.js file when needed?
    I have a problem of having more than one route file. Each route right now is connecting to the database, I would think one connection would be better.

    I seriously can’t find any information about this one the web, every example shows the connection either being formed in the route or in app.js (and not used beyond that).

    • John Moses February 17, 2014 at 5:00 pm #

      I have used this as documentation before. This is a big problem though, as you will find you will create a lot of open connections and they will all sit there. In Linux, an open socket is a process and there is a set max of how many processes run on the OS. We were hitting this, the solution is to call db.close() after each operation.

      The official documentation points this out.

      In short, beware if you are copy and pasting code as it handles connections incorrectly.

  88. Marcus Hammarberg January 26, 2014 at 7:57 am #

    Thank you – just what I was looking for.

    That it should be so hard to write a express intro without the generators… You did it. In a great way!


  89. Nec January 27, 2014 at 7:03 pm #

    Thank you so much for this tutorial , helps me a lot.

  90. Melih Mucuk March 6, 2014 at 5:25 pm #

    A little mistake on “wines = require(‘./routes/wines’); ” line. It will be require(‘../routes/wines’); Anyway, thanks for great article !

  91. Valtido March 16, 2014 at 7:41 am #

    Hi, I like your structure, one question I had was, What, would you use to get the “Wine” form, then use POST to add that “wine”???

  92. mobile games for girls April 11, 2014 at 8:13 am #

    My coder is trying to persuade me to move to .net
    from PHP. I have always disliked the idea because of the expenses.
    But he’s tryiong none the less. I’ve been using Movable-type
    on numerous websites for about a year and am concerned about switching
    to another platform. I have heard good things about
    Is there a way I can transfer all my wordpress posts
    into it? Any help would be greatly appreciated!

  93. pankaj April 11, 2014 at 9:10 pm #

    So nice of you,
    You makes life easier.
    everything work smoothly.

    Thanks for this tutorial.

  94. lzzluca April 17, 2014 at 6:55 am #

    Nice one! Thanks :)

  95. It’s perfect time to make a few plans for the longer term and it’s time to be happy.
    I have learn this submit and if I may just I wish to
    counsel you few attention-grabbing issues or tips.
    Perhaps you can write next articles relating to this article.
    I desire to read even more things about it!

  96. Brazil chanel April 18, 2014 at 4:06 pm #

    cheap chanel bags uk
    I am extremely inspired along with your writing talents and also with the layout in
    your blog. Is this a paid subject matter or did you customize it yourself?
    Either way stay up the nice quality writing, it’s
    rare to look a great weblog like this one today..

  97. Dan April 18, 2014 at 6:30 pm #

    Why not use:

    ‘npm init’


    ‘npm install express –save’


  98. buy ammo April 19, 2014 at 4:32 pm #

    Everyone lovers what you guys are usually up too. This type of clever
    work and reporting! Keep up the verty good works guys
    I’ve added you guys to our blogroll.

  99. pinterest April 19, 2014 at 7:38 pm #

    My brother recommended I might like this web site.
    He was totally right. This post actually made my day. You can
    not imagine simply how much time I had spent for this information!


  100. telecharger teamviewer April 21, 2014 at 6:30 am #

    When someone writes an piece of writing he/she retains the plan of a user in his/her mind that
    how a user can be aware of it. Therefore that’s why this article is amazing.

  101. keratosis pilaris treatment April 21, 2014 at 12:22 pm #

    This Keratosis Pilaris procedure equipment has been found to
    generally be actor at the root cause of Keratosis Pilaris indeed, this
    will pile-up involving abnormal required protein amounts round the follicles in addition to appropriately snacks any indications.
    The histologic picture shows a dense inflammatory infiltrate composed of small always faithfully comply with a topical
    or oral medicine regime. If acne and dry skin are your troubles, you could be
    better served finding a blemish skin care product that can fight both acne
    blemishes and moisturize the skin at the simultaneously.

  102. fun mobile games April 21, 2014 at 1:41 pm #

    I really like your blog.. very nice colors
    & theme. Did you create this website yourself or did you hire someone to do it for
    you? Plz respond as I’m looking to construct my own blog and would like to know where u
    got this from. kudos

  103. .223 ammunition for sale April 21, 2014 at 6:24 pm #

    With havin so much written content do you ever
    run into any problems of plagorism or copyright infringement?

    My site has a lot of unique content I’ve either written myself or outsourced but
    it seems a lot of it is popping it up all over the internet without my
    authorization. Do you know any solutions to help stop
    content from being ripped off? I’d definitely appreciate

  104. watch chef online April 23, 2014 at 5:21 am #

    Nice post. I was checking constantly this blog and I am impressed!
    Extremely useful info particularly the last part :) I care for such info a
    lot. I was seeking this particular information for a very
    long time. Thank you and good luck.

  105. gotoo April 23, 2014 at 7:28 am #


    great post!

    Thank you very much for this great and simple demonstrator !

    Dear Christophe, would it be possible to do the same thing using a SQL database (instead of mongoDB) ?
    If yes, could you give us a sample code of what the new “wines.js” would look like ?
    is Backbone.js only working with a mongodb?

  106. xfry April 23, 2014 at 4:42 pm #

    Amazing :D

    So good example about the easy way to create API without so much knowledge about nodejs+mongodb+express



  1. NodeCellar: Sample Application with Backbone.js, Twitter Bootstrap, Node.js, Express, and MongoDB - October 4, 2012

    [...] my previous post, I shared my recent experience building a RESTful API with Node.js, MongoDB, and [...]

  2. Confluence: Technology Wiki - October 9, 2012

    A Beginners Introduction to Node.js…

    I have recently learned how to write mobile apps u…

  3. Express: Links, News And Resources (2) « Angel ”Java” Lopez on Blog - November 2, 2012

    [...] Creating a REST API using Node.js, Express, and MongoDB [...]

  4. Node.js / MongoDB tutorial | Aviv Roth - November 28, 2012

    [...] would highly recommend the Node.js / MongoDB tutorial for making a RESTful web service here.  It nicely combines all of the required technologies, so you get to learn multiple things at [...]

  5. REST API with Node.js, Express, MongoDB « rg443blog - January 11, 2013

    [...] Creating a REST API using Node.js, Express, and MongoDB [...]

  6. My progress with learning Mongo and Ember | Ben Chadfield - February 2, 2013

    [...] to build a simple site with Node.js, Express, Mongo and Backbone. The first part is a good guide on building the API, which I followed. The second is really a link to a github repository for the finished product. I [...]

  7. node.js と express と MongoDBでREST APIを作るのに参考になったページ | ssdkfk - March 28, 2013

    [...] 以下です。 [...]

  8. Node.js for beginner | wizti - blog - April 14, 2013

    [...] Creating a REST API using Node.js, Express, and MongoDB [...]

  9. 3WDOC, Node, Javascript – Une expérience de développement mixant 3WDOC et Node.js pour un service à valeur ajoutée « 3wdoc - May 24, 2013

    [...] Creating a REST API using Node.js, Express, and MongoDB [...]

  10. 3WDOC, jQuery, HTML5, SaaS – The first version of the API documentation 3WDOC « 3wdoc - May 28, 2013

    [...] Creating a REST API using Node.js, Express, and MongoDB [...]

  11. Express.js | M's Web Dev - June 25, 2013

    [...] create a RESTful API with mongoDB, express and [...]

  12. Lindsey Learns APIs | - October 23, 2013

    [...] I learn better by doing so maybe make our own little API? Unsurprisingly, the internet has us covered. Let’s Create your first API. This is in PHP and very straightforward. But if you’re like me, you may want something in our own favorite web app language: JavaScript! So let’s go ahead and try Creating a REST API Using Node.js. [...]

  13. Hosting Your Own API | Write Wrecked Software - October 28, 2013

    [...] applications. I’ve tried several different ways of implementing the web service and landed on one implementation I found particularly simple and elegant, especially in comparison to the implementation I was using [...]

  14. DELETE request pending for a long time then fails | Technology & Programming - November 10, 2013

    [...] am playing with nodejs/expressjs/angularjs with MondgoDB on Ubuntu 12.04. I was going through this example. When I tested this locally, deleting a wine worked just fine. But after deploying to Ubuntu 12.04 [...]

  15. Create a RESTful API with Static Models using NodeJS and ExpressJS | API Buffet - November 21, 2013

    [...] Creating a REST API using Node.js, Express, and MongoDB [...]

  16. Create a RESTful API with Static Models using NodeJS and SailsJS | API Buffet - November 21, 2013

    [...] Creating a REST API using Node.js, Express, and MongoDB [...]

  17. 33 of the Best Front-End Development Resources | Simpixelated - December 7, 2013

    [...] Creating a REST API using Node.js, Express, and MongoDB | Christophe Coenraets [...]

  18. How to start with node.js : PHP, JavaScript, C++, JAVA, Programmer, software developer - February 11, 2014

    […] […]

  19. Starting out with Node.js | koding notes - February 21, 2014

    […] Here is an excellent guide for starting out with Node.js, the Express framework, and MongoDB: click me. […]

Leave a Reply