<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Thieves Like Us]]></title><description><![CDATA[Opinions and code. But mostly opinions.]]></description><link>http://brianmajewski.com/</link><generator>Ghost 0.6</generator><lastBuildDate>Wed, 08 Apr 2026 10:06:32 GMT</lastBuildDate><atom:link href="http://brianmajewski.com/tag/mongodb/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[(Re)Learning Backbone Part 4]]></title><description><![CDATA[<p><em>(Note: The code for this series is available on <a href="https://github.com/bmajewski/relearning-backbone">Github</a> - To get the code in preparation for this installment, checkout commit: <a href="https://github.com/bmajewski/relearning-backbone/commit/d82adb485a608278b2003415cab536503c40d5d2">d82adb485a608278b2003415cab536503c40d5d2</a>)</em></p>

<p><strong>Database Integration</strong></p>

<p>A lot of tutorials wave their hands at this point and assume you have a database connected. Worse, some will have you write stubs and</p>]]></description><link>http://brianmajewski.com/2015/02/19/relearning-backbone-part-4/</link><guid isPermaLink="false">6735c52a-db17-41c0-a71f-1fe0a8ccfa47</guid><category><![CDATA[javascript]]></category><category><![CDATA[mongodb]]></category><category><![CDATA[node]]></category><category><![CDATA[express]]></category><category><![CDATA[mongoose]]></category><category><![CDATA[postman]]></category><category><![CDATA[crud]]></category><dc:creator><![CDATA[Brian Majewski]]></dc:creator><pubDate>Fri, 20 Feb 2015 04:17:04 GMT</pubDate><media:content url="http://brianmajewski.com/content/images/2015/02/Mongoose_-PSF-.png" medium="image"/><content:encoded><![CDATA[<img src="http://brianmajewski.com/content/images/2015/02/Mongoose_-PSF-.png" alt="(Re)Learning Backbone Part 4"><p><em>(Note: The code for this series is available on <a href="https://github.com/bmajewski/relearning-backbone">Github</a> - To get the code in preparation for this installment, checkout commit: <a href="https://github.com/bmajewski/relearning-backbone/commit/d82adb485a608278b2003415cab536503c40d5d2">d82adb485a608278b2003415cab536503c40d5d2</a>)</em></p>

<p><strong>Database Integration</strong></p>

<p>A lot of tutorials wave their hands at this point and assume you have a database connected. Worse, some will have you write stubs and timeouts to simulate connection delays. If you know what you're doing, these can be a quick way to get a screen or feature running. If you're building from the ground up, you're just delaying the inevitable. Plus, if you've never done it before, figuring out how to wire it in later can be a challenge.</p>

<p><strong>MongoDB and mongoose</strong></p>

<p>Earlier in this series we installed <a href="http://www.mongodb.org/">MongoDB</a>. Ensure that you have a running copy before continuing. For a GUI front end, I like using <a href="https://github.com/jeromelebel/MongoHub-Mac">MongoHub</a>. <a href="http://mongoosejs.com/">Mongoose</a> is an object modeling solution that lets you write simple schema based objects to work between your Node server and your Mongo database. It has hooks for validation, query building and more, and with a healthy plugin ecosystem can do nearly anything you throw at it. We'll only scratch the surface of its feature set.</p>

<p>To install mongoose, run:</p>

<pre><code>npm install mongoose --save  
</code></pre>

<p>We'll need to tell our app how to connect to MongoDB. In our <code>server.js</code> file, add  </p>

<pre><code>var mongoose = require('mongoose');  
</code></pre>

<p>to the dependencies section at the top. Then underneath that, add  </p>

<pre><code>mongoose.connect('mongodb://localhost:27017/rlbb');  
</code></pre>

<p>If you configured MongoDB to run on another port, edit the above the string. <code>rlbb</code> is the name of our database and will be created if not present. Here is also where we would add things like database username, password, and the like if we had them.</p>

<p>Now, let's create a User model. Under <code>app/models</code>, create <code>user.js</code></p>

<pre><code class="language-javascript">var mongoose = require('mongoose');  
var Schema = mongoose.Schema;

var UserSchema = new Schema({  
    name: String,
    email: {type: String, required: true, index: {unique: true}},
    password: {type: String, required: true, select: false}
});

module.exports = mongoose.model('User', UserSchema);  
</code></pre>

<p>Here, we've pulled in our mongoose dependency and created a User Schema object. Mongoose uses the Schema as representation of a MongoDB collection and the base of its functionality. We've defined a <strong>name</strong>, an <strong>email</strong>, and a <strong>password</strong>. Along with the property names, we've defined their <em>SchemaType</em>, in this case, they are all Strings. For email and password, we've also included some additional properties. <em>required</em> indicates that the field must be present to be valid. Other validators include <em>min</em>, <em>max</em>, <em>match</em>, and custom validators can be created. For email, which we will use as our username, we create an index for it, and put a <em>unique</em> constraint on it. For password, we indicate that normal retrieval of this object from the collection should <em>not</em> include the password field. This prevents it from going across the network. When we add authentication later, we will explicitly ask for the password. Finally, we create a mongoose model from the schema and export it.</p>

<p><strong>Our First REST Endpoints</strong></p>

<p>So, we have a model of our User data. We now need a way to retrieve it from and write it to the database. In this app, all of our API URLs will start with <code>/api/</code> and then follow with the appropriate REST endpoints. For user, we will end up creating:  </p>

<dl>  
    <dt>/api/users</dt>
    <dd>POST - With a POST request, a new user will be created.<br>
    GET - With a GET request, this will return all users.
    </dd>

    <dt>/api/users/:user_id</dt>
    <dd>GET - With a GET request, this will return a single user with an ID that matches <i>:user_id</i>.<br>
    PUT - With a PUT request, the user indicated will be updated.<br>
    DELETE - With a DELETE request, the user indicated will be deleted.</dd>
</dl>

<p>With just two endpoints, and using the HTTP verbs, we can satisfy our basic CRUD requirements. To define these, we will create an Express router and then have Express <em>use</em> it, much like we did with the static assets directory and the catch all request handler.</p>

<p>Under <code>app/routes</code>, create <code>user.js</code> <sup id="fnref:1"><a href="http://brianmajewski.com/2015/02/19/relearning-backbone-part-4/#fn:1" rel="footnote">1</a></sup>.</p>

<pre><code class="language-javascript">var bodyParser = require('body-parser');  
var User = require('../models/user');

module.exports = function (app, express) {  
    var userRouter = express.Router();

    userRouter.get('/', function (req, res) {
        res.json({message: 'api is loaded'});
    });

    userRouter.route('/users')
        .post(function (req, res) {
            var user = new User();
            user.name = req.body.name;
            user.username = req.body.username;
            user.password = req.body.password;

            user.save(function (err) {
                if (err) {
                    if (err.code === 11000) {
                        return res.json({success: false, message: 'Duplicate username.'});
                    } else {
                        return res.send(err);
                    }
                } else {
                    res.json({message: 'user created'});
                }

            });
        })
        .get(function (req, res) {
            User.find(function (err, users) {
                if (err) {
                    res.send(err);
                }
                res.json(users);
            })
        });

    userRouter.route('/users/:user_id')
        .get(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);
                res.json(user);
            })
        })
        .put(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);

                if (req.body.name) user.name = req.body.name;
                if (req.body.email) user.email = req.body.email;
                if (req.body.password) user.password = req.body.password;

                user.save(function (err) {
                    if (err)res.send(err);
                    res.json({message: 'user updated'});
                });
            });
        })
        .delete(function (req, res) {
            User.remove({_id: req.params.user_id}, function (err, user) {
                if (err) res.send(err);
                res.json({message: 'user deleted'});
            })
        });

    return userRouter;
};
</code></pre>

<p>This looks like a lot, but it's fairly straightforward. Let's tackle it a chunk at a time.</p>

<pre><code class="language-javascript">var bodyParser = require('body-parser');  
var User = require('../models/user');  
</code></pre>

<p>Here will pull in our dependencies. We will use <em>body-parser</em> to get the data that comes with the PUT and POST requests and <em>User</em> is the user model we just created.</p>

<pre><code class="language-javascript">    var userRouter = express.Router();

    userRouter.get('/', function (req, res) {
        res.json({message: 'api is loaded'});
    });
</code></pre>

<p>Here we create an instance of an Express router. To give us a way to verify our routes have been initialized properly, we create a default route <code>api/</code> that will respond with a canned message. If there are problems we can use this to see if it is a server or database issue.</p>

<pre><code class="language-javascript">userRouter.route('/users')  
        .post(function (req, res) {
            var user = new User();
            user.name = req.body.name;
            user.email = req.body.email;
            user.password = req.body.password;

            user.save(function (err) {
                if (err) {
                    if (err.code === 11000) {
                        return res.json({success: false, message: 'Duplicate username.'});
                    } else {
                        return res.send(err);
                    }
                } else {
                    res.json({message: 'user created'});
                }

            });
        })
        .get(function (req, res) {
            User.find(function (err, users) {
                if (err) {
                    res.send(err);
                }
                res.json(users);
            })
        });
</code></pre>

<p>Here we create the <code>api/users</code> route and handle both the POST and the GET cases. In the POST block, we create a new User, set the fields with data from the request body, and save it. Mongoose handles the heavy lifting of creating the query and talking to the database. We perform some basic error-handling, and return an appropriate message to the client.</p>

<p>In the GET block, we call a static model method on User to retrieve all the stored users and return them. Once again, mongoose takes care of the details.</p>

<pre><code class="language-javascript">userRouter.route('/users/:user_id')  
        .get(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);
                res.json(user);
            })
        })
        .put(function (req, res) {
            User.findById(req.params.user_id, function (err, user) {
                if (err) res.send(err);

                if (req.body.name) user.name = req.body.name;
                if (req.body.username) user.username = req.body.username;
                if (req.body.password) user.password = req.body.password;

                user.save(function (err) {
                    if (err)res.send(err);
                    res.json({message: 'user updated'});
                });
            });
        })
        .delete(function (req, res) {
            User.remove({_id: req.params.user_id}, function (err, user) {
                if (err) res.send(err);
                res.json({message: 'user deleted'});
            })
        });
</code></pre>

<p>Here we create the <code>api/users/:user_id</code> route. Express will take the value in the request that maps to the <code>:user_id</code> section and create a request parameter that we can use. In the GET block, we use mongoose's <em>findById</em> method to retrieve a specific user. In the PUT block, we again retrieve the requested user, update its information with data from the request body, then save it. Finally, in the DELETE block, we use mongoose's <em>remove</em> function to delete the specified user.</p>

<p>Now it's time to wire the router into the server. In <code>server.js</code>, <strong>after</strong> the static directory declaration, add the following</p>

<pre><code class="language-javascript">// already in our file
app.use(express.static(__dirname + '/public'));

// ADD THESE TWO LINES
var userRoutes = require('./app/routes/user')(app, express);  
app.use('/api', userRoutes);

// already in our file
app.get('*', function(req,res){  
    res.sendFile(path.join(__dirname + '/public/index.html'));
});
</code></pre>

<p>First we create the routes, by requiring the file and passing it the two needed fields, app and express. (Go back and look at how we declared our router definition and you will see we have these two params listed). Then, we tell our server to <em>use</em> the routes. Remember, order is important. First our static files, then our API routes, and finally the catch all to serve up our home page. If we added our routes after the catch all, they would never be hit.</p>

<p>If we were to run our server now, with <code>nodemon server.js</code> we would be able to get and set users via HTTP. But... we don't have any users yet, and we don't have screens to input data. Any easy solution is to use something like <a href="https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm/related?hl=en">Postman - REST Client for Chrome</a> (all the browsers have similar tools). In the URL field, enter <code>localhost:1337/api</code> and make sure GET is selected in the dropdown. When you hit send, you should see our test message returned in JSON format. </p>

<p>We can do a similar task to add a user. Set the URL to <code>localhost:1337/api/users</code>, the method to POST, select <code>raw</code> for our input data and add</p>

<pre><code>{ "email" : "hireme@brianmajewski.com", name: "Brian M", password: "123456Secure!"}
</code></pre>

<p>These are the fields we defined on our User model.</p>

<p>We also need to set our content type, so select Headers, and for name put <code>Content-Type</code> and value put <code>application/json</code>. If we're configured right, you should get a response back saying user created. To see our new user, hit the same URL, with GET, and you should receive a response similar to</p>

<pre><code>[
    {
        "_id": "54e6b162eb2ac61c54e9b80f",
        "email": "hireme@brianmajewski.com",
        "name": "Brian M",
        "__v": 0
    }
]
</code></pre>

<p>Notice: Our password is not returned, as we specified in our schema. Experiment with the other routes and verify that you can update and delete users as well.</p>

<p>So there you have the basics for all CRUD operations for your app. Whether you are storing Widgets, Gizmos, Comments, or Reviews, you will follow the same basic pattern. Later, when we add authentication, you'll see how we can enhance mongoose's standard methods to perform extra functionality, such as encrypting the password, before saving the user.</p>

<p>To get the code with these updates checkout commit <a href="https://github.com/bmajewski/relearning-backbone/commit/18b0d51ee45d966abf9293be9a5fe25c6af8c6a6">18b0d51ee45d966abf9293be9a5fe25c6af8c6a6</a></p>

<p><strong>Next Steps</strong></p>

<p>With a functional backend in place, we will begin to create our front end web application. We'll look at using Bower to manage dependencies and RequireJS to load modules.</p>

<p>(<strong>UPDATE</strong>: There was a bug in the PUT block of the /users/:user_id route - <em>username</em> should have been <em>email</em> - This bug was fixed in the Chapter 7 version of the code on Github and in the text above)</p>

<div class="footnotes"><ol>  
    <li class="footnote" id="fn:1">
        <p>Some people prefer to include the function in the name, such as userModel.js and userRoute.js. I go back and forth on this. They are namespaced by their directory structure, so if there is no chance I am going to get them confused, I'll shorten them like I did here. You can name them mickey, pluto, and goofy if that floats your boat. I prefer frameworks without magic naming conventions.<a href="http://brianmajewski.com/2015/02/19/relearning-backbone-part-4/#fnref:1" title="return to article"> ↩</a></p><p>
    </p></li>
    </ol></div>]]></content:encoded></item><item><title><![CDATA[(Re)Learning Backbone Part 2]]></title><description><![CDATA[<blockquote>
  <p>Opinions are like birthdays: everyone has one and I heard about yours on Facebook.</p>
</blockquote>

<p><strong>Tool Sets and Libraries</strong></p>

<p>This is easily the most opinionated part of this process. I am always open to code changes; hearing the viewpoints of other developers who may have more experience or a different perspective</p>]]></description><link>http://brianmajewski.com/2015/02/13/relearning-backbone-part-2/</link><guid isPermaLink="false">7625c66a-c76c-42cd-9b86-2f382fbdbb44</guid><category><![CDATA[backbone]]></category><category><![CDATA[javascript]]></category><category><![CDATA[intellij]]></category><category><![CDATA[mongodb]]></category><category><![CDATA[node]]></category><category><![CDATA[brew]]></category><category><![CDATA[mac]]></category><dc:creator><![CDATA[Brian Majewski]]></dc:creator><pubDate>Fri, 13 Feb 2015 16:36:57 GMT</pubDate><media:content url="http://brianmajewski.com/content/images/2015/02/construction408661.jpg" medium="image"/><content:encoded><![CDATA[<blockquote>
  <img src="http://brianmajewski.com/content/images/2015/02/construction408661.jpg" alt="(Re)Learning Backbone Part 2"><p>Opinions are like birthdays: everyone has one and I heard about yours on Facebook.</p>
</blockquote>

<p><strong>Tool Sets and Libraries</strong></p>

<p>This is easily the most opinionated part of this process. I am always open to code changes; hearing the viewpoints of other developers who may have more experience or a different perspective often lead me to change my code. We call it <em>software</em> for a reason. It should be malleable. It should adapt. When it comes to my tools, however, that's a different story.</p>

<p><strong>OS - Mac OS X</strong></p>

<p>Let's get the holy war out of the way. If you use Windows, more power to you. You must like the extra challenges of playing on <em>Expert</em> mode. For me, there are three key reasons I develop on the Mac.</p>

<dl>  
<dt>Environment</dt>  
<dd>Most every environment I am going to deploy to is a *nix variant. Having a BASH (or similar) shell integrated into the OS allows me to create workflows that work everywhere I do.</dd>  
<dt>The Cool Kids Use It</dt>  
<dd>Most of the developers and designers that I read and learn from are using it. This isn't simply a case of "me too!" This is a case where I want zero impediments in my way of completing my task. If they recommend a tool or a library or even some non-web-dev related utility, I'd rather be able to copy them than go searching for an equivalent.</dd>  
<dt>Comfort</dt>  
<dd>I've worked on Apple hardware since the Apple][ days. It just makes more sense to me.</dd>  
</dl>

<p>So, yeah, use Windows if you want. Good luck with that.</p>

<p><strong>IDE - Jetbrains IntelliJ IDEA (or Webstorm)</strong></p>

<p>I'm maybe a little bit more flexible on this issue, but not by much. As a professional developer who works with a number of different languages and technologies, having a tool that works across all of them is something I find is worth my investment in time and money. I've been using it since Version 1 when I met the original developers at a conference in Prague. It has been my <a href="https://www.jetbrains.com/idea/">IDE of choice</a> ever since. Any good text editor like <a href="http://www.sublimetext.com/">Sublime</a> or <a href="https://atom.io/">Atom</a> can be a useful tool with the right setup and plugins. IDEA mostly works out of the box with deep support for things like Node, Angular, Grunt, and the like.</p>

<p><strong>Brew</strong></p>

<p><a href="http://brew.sh/">Brew</a> is "The missing package manager for OS X" and allows you to install and maintain the tools used to develop and build. Get it. Install it. If you like GUIs, get <a href="https://www.cakebrew.com/">Cakebrew</a>.</p>

<p><strong>Node</strong></p>

<p>We're going to use <a href="http://nodejs.org/">Node</a> to stand up a web server to serve our REST endpoints and access the database. <strong>DO NOT</strong> simply go to the website, download the package and install it. You'll end up in a world of hurt, having to run everything as <em>sudo</em>. Use Brew (see above). <code>$ brew install node</code>  Should we switch over to <a href="https://iojs.org/en/index.html">io.js</a>? Maybe? This is one of those rat holes I wanted to avoid with this project. Investigating io.js is an endeavor for another day.</p>

<p><strong>MongoDB</strong></p>

<p>Is <a href="http://www.mongodb.org/">MongoDB</a> the right database for your application? Who knows? For this project, we want a simple document datastore that has some easy integration with javascript. We could serve up JSON files instead of hitting a datastore, but that doesn't meet the requirements of having a fully functional application from soup to nuts to build off. We can always swap it out for another technology. Again, use Brew to install it.</p>

<p><strong>Next Steps</strong></p>

<p>At this point, we have the makings for a web server that can serve up data. Well, we have the tools anyways. In the next installment, we'll create a project structure and web server we'll use throughout the project.</p>]]></content:encoded></item></channel></rss>