Architecture recommendations & guidelines for a Node.js web application?

Architecture recommendations & guidelines for a Node.js web application?

Problem

I’m eager to begin a side project for learning purposes, and I’m seeking some guidance on which technologies/frameworks/libraries to use, and how to structure the application, at least at a high level. I’m a front-end developer, and while I’ve done some miscellanous work with server-side programming, databases, etc., this will be my first attempt to personally create a full-stack application. I’ve decided to use Node.js as the server-side environment, but that’s my only firm requirement.

I’ve already come up with an idea for the application. Here are some notes on its features:

  • This is another to-do list app. What primarily distinguishes it from your basic checklist is its adaptation of some aspects of the GTD system, as well as a nested/tree structure for the list (as opposed to a flat list, or a single level of nesting like GTD uses). I’m leveraging the metaphor of a tree, where the trunk is the foundation of the list, branches are projects and sub-projects, and the leaves are individual tasks.
  • Projects (branches) can have many sub-projects (branches off of other branches), and both projects and sub-projects can have many tasks (leaves). A project is any multi-step process that you can eventually complete, but you can’t actually physically do. Like GTD, you can only do a task that is defined as a physical action. For example, “get a bank loan” is a project (it’s a definable goal), “research lenders’ rates” is a sub-project (it moves you toward completing that goal), and “call the local Wells Fargo branch,” “visit the lending section of chase.com” and “email Bob for his recommendation” are all tasks (they are specific physical actions that you can take that advance the project/sub-project).
  • Once you’ve completed all of the tasks in a project (trimmed all of the leaves), that project is considered complete (the branch is cut off). Your goal is to continually prune the tree to keep it from overgrowing.
  • If you’re like me, you have a huge list of projects that are perpetually completed and replaced with new projects. The value in this application, aside from just storing your list, should be in its ability to guide you toward what to work on next. To this end, you can define an assortment of metadata about each task (just for tasks; you can’t do this for projects, since they’re simply buckets for organizing groups of tasks).
  • This metadata includes additional information about each task that you can sort and search upon. For example:
    • Context: What tools/situations do you need to complete the task? For example, to renew your driver’s license, you might need completed paperwork, and be at a specific location, during weekday business hours.
    • Deadline: Can this be done any time, or is there a hard date for completion?
    • Importance: Is this something you want to do, or something you need to do?
    • Time: How much time do you estimate you’ll need to complete the task?
  • Given this metadata, you can open the application at any time and quickly determine what to work on next, given your current (or imminent) context, impending deadlines, which tasks have the highest importance, how much time you have before your next commitment, etc. This saves you from having to scan the same flat list day-in, day-out and making the same mental calculations without having any organized/stored metadata about each task. You can either look at impending deadlines to figure out what needs to be done next, or you can choose what resources are currently available to you, which narrows down the list to only the tasks that are possible to complete.

The utility in this application will come from its ease/speed of use and from striking the right balance between simplicity and extensibility. To the former point, you should be able to edit project/tasks descriptions in place, click to toggle metadata, drag & drop to move tasks to different projects, etc. There should be minimal list management overhead. To the latter point, you should only have to enter as much metadata about each task as you care about or is useful to you, and thus get out of the application as much utility as you’ve put in in effort. If you want to use the app only to record and update your list items, that’s fine; if you want to finely manage deadlines, specify the importance of every task, etc., then that’s fine, too. The more you put into it, the more you get out of it, but there’s no enforcing data entry beyond a simple line item description for each project/task.

This all suggests to me a one-page web application (and ideally, eventually mobile-friendly) with perpetual saving in the background. You should be able to log in, move some stuff around, mark some stuff as completed, and close it down. No formalities, just like a written list. It will be an ever-evolving list that should ultimately save you time, not create the burden of extra overhead to track all of your small daily tasks.

So, given all of this, I’m seeking some recommendations on how to approach developing this application; essentially, how to architect it. Should I use a client-side MVC framework like Ember.js or Backbone.js? What database is best fit for storing this kind of data, and what should my schema look like? How do I approach CRUD/REST and routing? As a single-page app, will I have to resort to one huge controller? What does the data look like that I’m transporting between the server & browser? Again, my only hard decision has been to use Node.js on the server, since the point of this undertaking is mainly to leverage my JavaScript skills to dive further down the stack (and, hopefully, to come up with a useful application!). Everything else is wide open to recommendations.

Given your recommendations, I’m confident that I can dig into the specifics of these technologies and figure out how the pieces fit; I’m just mostly at a loss right now since there are so many options and approaches for how to structure an application, and while I’ve fixed a bug in a Rails view here and there, I’ve never architected a complete application; I don’t fully understand the fundamentals of how this all comes together. I’d love some feedback along the lines of “each task in the list can be a document; use Redis to store a JSON object with the properties of the task, and when a user updates a task in the browser, compose and send this object from the client to your controller to update the Redis document”. That’s probably total malarkey, but hopefully you get the point. Any links to tutorials, demos or other examples are also much appreciated – I’ve already read and watched a lot, but I can never seem to mentally map these more general explanations to my specific use cases.

Please let me know if there is anything I’ve been particularly naïve about, or any important details that I left out, or if it’s just not entirely clear what I’m asking for.

I also realize that this type of question isn’t the ideal use case for SO since there is no “right” answer, but I think the best answer will simply be the one that is most helpful.

Big thanks in advance for any help!

Problem courtesy of: Bungle

Solution

If I were building this, I would use Backbone.js, and use a simple RESTful CRUD interface (which Backbone’s default sync method is built for), but thats just me.

With this approach you could have a task model, extend that to a subtask model (adding in a parent attribute), and have each task (and thus subtask) having a collection of subtasks.

Syncing would be simple, as you can just use Backbones building sync method and a basic RESTful CRUD server.

You can include any validation you want right into your Backbone model, and bind to a tasks subtasks by listening to a custom event on that collection (triggered when a model in that collections state changes) to determine if the task (and all subtasks) are complete.

I know that this post is kind of upvoting Backbone alot, but it is a subjective question, and this is my opinion.

Server side I would recommend using Express, and you may be able to make use of the express-resources modules to make your REST implementation easier.

Again, this is just my opinion. Feel free to ask questions.

Solution courtesy of: Nick Mitchinson

Discussion

Leave a Reply

Your email address will not be published. Required fields are marked *