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.).
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.
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.
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.
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.
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..
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.
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?
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.
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?