Getting Started with NodeJS – Migrating RestBugs

I’m intrigued by node – partly because of all the recent hype and ‘cool kid’ factor – but mostly because I like the idea of having a single language context on both client and server.  Plus, the overall programming style for authoring Web apis feels similar to the style I enjoyed in sinatra.  At any rate, in an effort to better understand node, I’m porting RestBugs from ASP.NET Web API to node.

Here’s where I’m at currently – https://github.com/howarddierking/RestBugs/blob/NodeJS/RestBugs-Node/app.js

It feels like I’m actually close to a completely working application – however, there are a couple things (1 thing really) that’s keeping it from working, and before I go write a bunch of code to do something totally hacky, I would rather just ask you good people.  Here’s a sample of the type of code in question.

Here, I’m getting a JSON doc from MongoDB based on the id that was sent from my form and I want to execute a function on it.  That function is declared as a privileged method on a custom JavaScript object.

Now, you probably already know that the route handler code above won’t work.  Why?  Because MongoDB is giving me back a JSON object and I need to work with it as a Bug object.  If I was using JSON instead of form URL encoding for my POST input, I would likely run into the same problem on that side of the fence as well.  This leads me to my question:

What is the right way to think about moving between JSON input/output objects and “domain” objects?

My brain keeps telling me that my desire to map properties from one object to another (via my own code or a library) is wrong in a language like JavaScript, but I also came across some posts (http://erik.eae.net/archives/2005/06/06/22.13.54/) that seem to indicate that tricks like swapping out the prototype may be an even worse idea.

About Howard Dierking

I like technology...a lot...
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • John Teague

    You can still do arbitrary schema with Mongoose.  You can also create your document objects from your request object.  Here is what your Mongoose schema might looks like (I’m not an expert, so YMMV)
    var BugSchema = new Schema{    title:{type:String},    description:{type:String},    title:{type:String},    status:{type:String},    //embedded history    history:[HistorySchema]    //assuming you have user object as are reference, but you can nest as well    assignedTo: {type:ObjectId,ref:’User’},}BugSchema.methods.updateStatus = function(status,comment){    //do your work here}BugSchema.methods.activate = function(comment){    this.updateStatus(‘working’,comments);}Bug = mongoose.model(“Bug”,BugSchema);

    To Hydrate your Bug class from the response would be something like this:

    app.post(‘/bugs/new’, function(req, res){
    var bug = new Bug(res.body);
    //save does an upsert
    bug.save(function(err){//…});
    }
    and to use your bug methods
    //Static method
    Bug.findById(req.body.id,function(error,bug){
    bug.updateStatus(req.body.comments)
    bug.save(function(err){//..}

    If you choose to go the extend route, go with the underscore library.

  • Anonymous

    Given the whole, “mongo can store arbitrary json” pitch (which I like at the moment), I’m not sure what value I gain by putting a model on top – though perhaps I just don’t understand how Mongoose works to make an informed decision.  That said, even if Mongoose can solve the object conversion on the database side, I’ll still have the exact same problem on the inbound data side (e.g. json coming from the request body).

    My hope was that there was a general solution that could solve the problem on both ends.

    I’m enticed by the extend approach – any good examples/implementations that you know of?

  • John Teague

    Your missing an abstraction that creates your Bug object from the data stored in Mongodb.  I would recommend using Mongoose to handle this for you.  You can either you create your models with Mongoose and attach methods to the models or you can embed the Mongoose schema behind your own object and the delegate to the model objects any peristence related work.

    If you wanted to roll your own, then you will need to something along the lines of the extend approach.

  • HarryC

    Javascript is still super-awesome … That is what I learned when working with JavaScript – we are so used to doing clever tricks that we become afraid of simple yet straight forward solutions …

  • Anonymous

    That’s definitely my ‘get it working’ approach – however, i keep thinking “hey, this is JavaScript – shouldn’t I be able to do something super-awesome like replace the prototype and rely on duck typing to have it just work?”

  • Cliffeh

    Sorry, I meant this:

    var bug = new Bug();
    _.extend(bug, doc);

    Then call bug.activate()

  • Cliffeh

    Maybe this is a little simplistic, but what about just copying all the properties from your JSON object to a Bug object? I use underscore, which has an extend method:

    var bug = new Bug();
    _.extend(bug, req.body);