Main

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 http://nodejs.org, 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 nodejs.org 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 http://downloads.mongodb.org/osx/mongodb-osx-x86_64-2.2.0.tgz > ~/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
    ./bin/mongod

  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
    ./bin/mongo

    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.

Share this Article:

101 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.

      Source- http://tools.ietf.org/html/rfc4627:

      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 ) ]
      end-object

      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.

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

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

      http://mongodb.github.com/node-mongodb-native/driver-articles/mongoclient.html

      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?)

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

        A nice summary
        http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

    • 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. mfkrh-ar.com October 3, 2012 at 10:42 pm #

    mfkrh-ar.com 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

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

    Thanks a lot, really nice indeed. But I think we should read this one: http://www.smartjava.org/content/presentation-rest-hateoas

  7. mfkrh-ar.com 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
      app.use(express.bodyParser());

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

    Pretty good so far, but where is this defined?
    “http://localhost:3000/wines/search/Chateau”

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

      Ken,

      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: deployd.com/video.html
    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 #

      David,

      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 http://nodecellar.coenraets.org/wines/1

    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 db.open(…)

    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) {
      populateDb();
      }
      });

      • 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.”

    http://mongodb.github.com/node-mongodb-native/markdown-docs/collections.html#selecting-collections

    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.open(function(err, db) {
    if(!err) {
    console.log(“Connected to ‘winedb’ database”);
    db.createCollection(‘wines’, {safe:true}, function(err, collection){
    console.log(err);
    if (!err){
    console.log(“The ‘wines’ collection doesn’t exist. Creating it with sample data…”);
    populateDB();
    } 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…”);
    populateDB();
    } 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){
      populateDB();
      }
      });
      });

      • 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.open(function(err, 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…”);
          populateDB();
          }
          });
          }
          });

    • 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 = req.params.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,
      Xavier

      • 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) {
        console.log(err);
        }

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

        // 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.”);
        console.log(err.message);
        }
        });
        }
        } catch(err) {
        console.log(“There has been an error parsing your JSON”);
        console.log(err);
        }
        })
        };

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

        And in the db.open method (still in ./routes/wines.js), I have replaced it as follows:

        db.open(function(err, db) {
        if(!err) {
        console.log(“Connected to ‘winedb’ database”);
        db.collection(‘wines’, function(err, collection) {
        checkDBSeeding();
        });
        }
        });

        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 #

    Hi,
    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 #

      @Td

      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 db.open 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:

    app.use(express.logger(‘dev’));

    app.use(express.bodyParser());

  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.

    Cheers,

    Bob

  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”}’ http://127.0.0.1:3000/users/

    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 –>http://cl.ly/image/3t1N351K0v19
    The error says:

    events.js:72
    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 Function.app.listen (/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:

    Change:
    var Server = mongo.Server,
    Db = mongo.Db,
    BSON = mongo.BSONPure;
    To:
    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);
    app.post(base, 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

  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.

Trackbacks/Pingbacks

  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 http://coenraets.org/blog/2012/10/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

    [...] 以下です。 http://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/ [...]

  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 MongoDBhttp://coenraets.org/blog/2012/10/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 MongoDBhttp://coenraets.org/blog/2012/10/creating-a-rest-api-using-node-js-express-and-mongodb/ [...]

Leave a Reply


8 − 4 =

Powered by WordPress. Designed by Woo Themes