My Current Ideal App-Dev Routine, April 2014
Sun Apr 27 14:00:04 EDT 2014
Though most of my paying work involves working with clients' creaky old databases, greenfield projects will always have my heart. For these and for my side projects, I've been moving towards an ideal Domino-app strategy that seems to serve me well.
The Setup
My apps consist of at least two NSFs: one for the app itself and at least one for data. The only non-design notes in the app NSF are for app configuration, and even then I keep it limited. Everything else goes in the "data" databases, which have designs consisting only of views, forms (rarely), and any agents needed for migration between versions.
This has several advantages I've talked about before. Importantly, other than the "Don't allow URL open" problem, which can be avoided entirely, I've encountered no down sides to this approach. The amount of flexibility it provides and the discipline it imposes pay massive dividends while not significantly increasing hassle. I recommend everyone do it. I try to keep an eye towards future scaling/separation needs as well: I tend to give my app configuration options where each document category are stored (say, Tasks/Projects vs. Clients vs. Update Notifications), even if I set all of them to the same location.
Scaffolding
As you might expect, I use the latest version of my XPages Scaffolding project for the app NSF. Now that my model framework supports attachments, there's little preventing me from using it extensively for data access in future projects.
Once those classes settle down a bit more, I expect that I will package them up as plugins so I can have a consistent "frostillic.us Framework" to attach a project to, allowing me to roll out bug fixes to major+minor versions (e.g. frostillicus.framework_1.2) without using classic-style design inheritance.
One of the potential future bonuses of using my model framework combined with inherent data separation is that I will be able to write adapters for my framework to connect to other data sources without the app having to care much (beyond the config document for pointing to the other data store). As long as I do the legwork to write the model classes, the bulk of the app won't have to care whether it's talking to Domino, JDBC, CouchDB, or a CSV in the data directory.
Source Control
I use Git early and often. As soon as I start work on a project, I create a repository on Bitbucket and then commit the app and data NSFs to it immediately. This has a couple crucial implications:
- I try to focus my changes into conceptual units for commit purposes. Though it's exceedingly rare that I actually need to reverse a commit, the better I am about only committing related changes (i.e. not commits like "implemented a wave of client requests"), the easier it is to do so if needed.
- I develop using either a local Domino server or NSFs on a shared server that is dedicated to my current machine. If, for example, I want to work on the same project on both my desktop and laptop, that means I will have two copies of each NSF even if they're on the same machine. This just saves a lot of hassle while simultaneously reinforcing the source-control-focused dev model.
Prototyping
I haven't had a chance to put this into real use yet, but, now that I'm a convert to renderers, I plan to get into the habit of doing my initial prototyping using standard ExtLib components with OneUI as the theme. I'll still have to keep an eye towards the eventual goal (for example: avoiding the Dojo-exclusive components or ones I don't really want to write renderers for if I'm not planning to actually deploy with OneUI), but this will make it much quicker to start laying down the common components of the app immediately without having to worry about specifically implementing Bootstrap-or-other-framework classes and HTML structure.
Because renderers are more difficult to write than custom controls with the HTML hard-coded, this will increase the overall development time, but the flexibility and off-loading of responsibility to later in the dev cycle will be worth it. Additionally, each render kit is easier to write than the last, particularly if I can reuse/extend previous work.
Deployment
As mentioned, the use of source control imposes a strict structure on development from multiple machines. This discipline contributes to dealing with production versions of the database. It's always been the case that it's a terrible idea to do work in a production version of a database, but Notes always made it so easy to get away with it. Fortunately, XPages' PITA compilation requirements and gotchas make this a terrible idea (who wants their app to go down because you opened it in Designer but forgot to install a required XSP library first?). This is all the worse when source control is involved: a bug in the SCM plugin or a missing network/VM share can easily destroy every design element in the target database. If it happens to be one dev DB among many, who cares? If it's your production DB, now you have a serious problem.
When I'm ready to deploy my changes, I do it via NTFs: I create NTF copies of any applicable dev NSFs and use them to replace the design of the production databases. Because these apps tend to be single instances, I don't bother with template names and design inheritance. In the case where there are many copies of the data databases (say, one core app and then one data DB per client), I'd probably use inheritance and replace the data DBs' NTF's design instead and immediately run the design task.
Since I have NTFs of each deployment sitting around, it makes it easy to roll a production DB back to a previous state. Though I don't currently, I plan to start tagging releases in Git (or just switch to GitFlow, which I've yet to use) to make this clearer as well.
Another improvement I'm considering making is to drastically limit my own rights to the production DB, to a max of Editor access. This way, there's an extra layer standing in between me and the terrible notion of opening the live DB in Designer. I figure I'll either use a dedicated deployment ID or use Full Access Administration mode to make deployments.
I've been feeling pretty good lately about this emerging scheme. A lot of it aligns with standard practices for non-Domino development (data/app separation, heavy source control) while still maintaining the benefits of Domino and XPages. And once this process is firing on all cylinders (namely, once I have skill in renderers to cover all of my regular needs), it should yield pretty impressive results when it comes to putting out fleshed-out, scalable apps quickly without making my development life down the line harder.