3

I'm working on a single page application on the node-webkit desktop app platform, which means 99.9% of all of the logic is written in JavaScript. Since this is a reboot of a project we're working on, I wanted to approach the architecture from more of an MVC approach on the client side.

I'm planning on creating a DAO layer for access to localStorage, IndexedDB, as well as Web services via REST requests. The problem is, the first tool I reach for to make HTTPS requests to the server is jQuery AJAX. It feels a bit weird to use jQuery in the DAO layer, even though I don't plan to manipulate the DOM, but it works really well on node-webkit and is a tried and tested tool for retrieving and sending data to the servers.

Despite the popularity of certain JavaScript application frameworks that have a certain way of doing things, we're not planning on using any frameworks other than JavaScript libraries that are fairly lightweight and unobtrusive, such as jQuery, Underscore, Mustache, Node.js modules, but nothing that forces us to unequivocally exclude certain technologies.

I'm planning to inject jQuery into the DAO layer for the purposes of making calls via AJAX to the Web services. My question is this:

  • How should I approach Web services? Do I treat Web services as just another data source like the local database?
  • Or do I just simply use the raw XMLHttpRequest object? What's the proven method for dealing with this architectural problem on the client side, without JavaScript frameworks?
  • 1
    FYI you can create a custom build of jQuery github.com/jquery/jquery#how-to-build-your-own-jquery – ZippyV May 1 '14 at 23:01
  • @ZippyV - Interesting concept, and it's one I considered. However, I'm not sure I'd personally go that route because of the overhead of maintaining updates, but you should totally consider adding that as an answer, assuming you can add more details. Someone else with this same problem might find that to be quite actionable. :) – jmort253 May 2 '14 at 1:21
  • Ok, so I look at this the other way around, and I think it applies to DAOs in many languages. What does JQuery get you? I mean, I see your stated answer, but my point is that the more core the library, the fewer dependencies you typically want it to have for exactly this type of reason. And typically the DAO layer is about as core as it gets. It seems like your own lightweight wrapper around XHR is a good bet unless you see big reasons not to... – J Trana May 21 '14 at 5:18
3

Treat Web services the same as any other data access:

To approach client side MVC architecture, without frameworks, we treated Web services in the same manner as we did localStorage and the local IndexedDB database. All code that involves requests to remote servers or that query a database or that read/write to localStorage happen in the model layer as DAO objects.

These were written using either the prototype pattern, the module pattern, or in some cases a combination of the two, using a modified factory pattern to treat objects as singletons in production but allowing us to "reset" them when unit testing so we keep tests self-contained.

They're generalized so that no application logic exists in this layer, and most of the code at this level can essentially be reused across future applications.

The services layer encapsulates the DAO layer, keeping the specific storage technology separate from the controller logic. Thus, pushing data to a remote server is seen as the same as inserting data into IndexedDB.

Used raw XMLHttpRequest to interface with Web services:

We chose not to use jQuery AJAX. Instead, we wrote a wrapper around XMLHttpRequest. There's no right or wrong answer here, but choosing not to use jQuery here allows us to stay focused on the rule of having no DOM manipulations in this layer. By wrapping the AJAX logic inside a prototype class, we set certain default headers, since most of what Web services deals with in our case is application/json data.

However, we did make an exception for jQuery Deferred. It didn't seem to make sense to write our own Observer implementation simply to be purists, and our logic behind this decision is that future professional programmers who work on this project with us have a better chance of understanding $.Deferred than some hand-rolled implementation. Many developers, on the other hand, we argued would have been exposed to XMLHttpRequest at some point in time, so being a purist here seemed less risky from the perspective of communicating to other developers what a piece of code does.

Analysis:

Earlier, I mentioned rules. We wrote up a series of "rules" designed to keep the code maintainable. For instance, rule #1 is that jQuery DOM manipulations only happen in a "view" layer. So the only jQuery we use in other layers is the $.Deferred object and nothing else.

We use $.Deferred throughout the application to keep certain logic in the layers where that belongs. For instance, we keep a persistent $.Deferred observer in the DOM click handlers in order to "notify" the controller that a click event has occurred so the controller can then delegate to other layers of the application to get/set, fetch/store, or perform other actions.

Using TDD as a development methodology, we've created small functions, where the largest is never more than a page, and most layers have a great deal of test coverage.

After a few months, the jury is still out on whether we should have used a framework, as much of what we've done could be generalized further into a reusable framework. We've learned quite a bit trying this, and I'm hoping this experience helps others who wish to develop client-side applications that involve a lot of asynchronous operations.

To give credit where it's due, I took inspiration from the following people:

For further reading on going framework-less, see Joe Gregorio's Zero Framework Manifesto

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.