Web App Architecture Checklist

Starting a new project – as a Tech Lead – I wish I had a checklist that reminded me all the important aspects to consider.

This is that checklist.

I’ve recently started reading Code Complete 2nd Edition, and I found the chapter about Architecture Prerequisites interesting, but out of date with the current development trends. So I thought about taking inspiration from it, adapting some of the advices to more Agile practices and narrowing it down to web development.

This list is not necessarily complete, nor mandatory, but it’s intended to be used as a memo.

Some of these issues naturally need to be addressed at the beginning, but most of them could be specified during the development cycle, depending on the delivery strategy.

Re-use VS Build

First and foremost: have you considered re-using pre existing solutions? If so, justify why (i.e. an open source framework, an existing library, a service already available, etc.).

Componentization

Modern architecture tends to favor small, independent web-services instead of monolithic applications. Have you defined the components in which your app could be split?

If you have the flexibility to do so, this doesn’t need to be defined at the beginning of the project. I’ve noticed for instance that using a cloud infrastructure allows a more flexible, evolutionary architecture. If your hosting is less dynamic it’s important you figure it out upfront, or the cost of change is going to be too high.

Data organization

What databases are going to be used, and why? Particular care should be put in identifying relationships between data. This could be done by analysing important use cases generated from the core business requirements.

Integration

No application is an island nowadays. Clarify the point of integration with all other internal applications (business core apps), or external (social networks, payment services, web APIs etc.). What protocols should be used? How will the integration been assessed?

I like the architectural principle of building “hard shells and soft cores”. The shell is the interface that the application expose, the core is the actual code. Focus should be put in specifying this interfaces and how they communicate.

Testing strategy

I believe thinking about the testing and stubbing strategy is really important at the beginning of a project. In the same way as TDD/BDD practices inform the design of the code, defining how the whole system will be tested generates useful insights on the architecture itself.

So, try to identify what kind of automation test suites will be necessary, and how and where the point of integration will be stubbed.

For instance: test JavaScript front-end in isolation using Mocha, test the Ruby back-end with RSpec, functional BDD acceptance tests using Selenium to exercise the whole app – except for the unstable dependencies. Etc.

Environments and path-to-production

How many environments are you going to need? How many can you budget? Think about: dev and QA environments, integration environment, production-like environment for load test, offline/online environment separation, disaster recovery and data-center replication..

Error handling

I’ve never done this upfront, but after reading it on Code Complete 2nd Edition I realized how important it is, and how much headache it could save. Basically, try to define how errors should be handled. See if you can define a common pattern for generic error scenarios. How will this errors manifest on the user interface? How will they propagate through your code? Do your back-end and front-end frameworks already have an error-catching strategy?

On a similar topic: define a logs strategy. How much you application will need to log? Where will the logs be stored? I personally agree with what Hugh Williams (eBay) said during a panel about scalability at 2012 PHP UK Conference: log everything you can.

Content management

How will the client manage the content? Do they need the capability to update content without doing a deployment? If so, do they need a user friendly interface and a proper CMS solution? Also, what about internationalisation? Have you thought about how this will affect your testing strategy?

Security

Have the security requirements been specified? Have a solution been proposed? How will these requirements be tested? What about data protection and PCI requirements?

Availability and performance

Have you discussed the availability requirements with the business? Are they just random numbers or have they a business meaning? How are you planning to do load testing and performance testing? Also, how are you going to monitor the availability? Start defining hooks for your monitoring tools and availability metrics.

Robustness and overengineering

What level of robustness your application needs? Is it going to be a medical surgery software where a minimal error may be fatal, or is it going to be a content-based website? Is this a code business application or is it a restricted prototype? I found defining the robustness upfront really usefull, because a lot of great developers tend to build the best robustness possible out of pride and professionality, but sometimes it may not be cost-effective.

Changeability

Can you identify what areas are more likely to change? If so, can you define a strategy to make change easier? For instance, if a specific data section is likely to change, using unstructured documents-based solution like MongoDB could make it easier.

Can you identify other “strategies to delay commitment”? What about using configuration files and features flags?

Debugging Node.js

I’ve never found the time to investigate better ways to debug Node.js than using console.log. So I’ve decided to do some googling and testing, and write-down here the result as a memo.

util.inspect

Just one little step better than using console.log, the util.inspect function generates a human-readable representations of the parameter specified. It’s like Ruby Object.inspect, but with some extra features.

I like using it like this:

// inspect the Boolean function constructor
// options: show hidden fields, 1 depth of recursion, use ANSI colors
util.puts(util.inspect(Boolean, true, 1, true));

In my terminal, this is the output:

A proper debugger

OK, let’s move to something more serious. Node.js has an easy to use built-debugger which hooks to the V8 JavaScript engine debugger. The best deal is using it via a package called node-inspector. It’s like a chain:

node-inspector (visual UI) -> Node.js debugger -> V8 debugger

This combination is really powerful. node-inspector uses the WebKit debugger as a UI. Here is a screenshot of me, inspecting an Express.js response object:

It’s also very easy to use. Just run node with --debug param, start node-inspector, and open a browser.

node-inspector can also be hooked to an existing process and can be easily used to do remote-debugging.

Resources

Hello world!

Hi everybody. So this is my first post. After more than 3 years I’m finally back writing a blog. My previous blog is still on-line. If you are curious, here it is: http://www.maverick.it/en/

Why WordPress.com? I admit it was a tough decision. My first plan was to build a custom blog engine using Node.JS and hosted on Heroku. Then I realised I would have to duplicate a lot of things I could get for free. I also like the fact that using a ready-made solution force me to focus on the contents and less on the technical details.

My plan is to use this blog to publish my technical discoveries and my thoughts about web development and technical team leadership.

So here we are. Let’s begin.