As a developer, you often find yourself in a situation where someone is describing some new system to be built, and you're trying to wrap your head around exactly what "it" is. Maybe it's a client with a potential new project, or maybe just a friend with another one of his "can't-miss" ideas for a new app. Regardless, the goal is essentially the same: through a simple conversation, you want to quickly size things up and help them figure out (a) whether it's technically feasible, and (b) if it is, how it could be built.
Early in my career, I'd usually cut right to the chase (or so I thought). I'd get a basic sense for what the system needed to do, and then I'd start sketching out my ideas for the tech stack:
"Ok...it's a B2C commerce web app here...pretty standard...so probably React, NodeJS, and Mongo."
Or whatever. The point is, as an opening gambit, this wasn't very effective. While it might convey some level of confidence to the "business" owner that I was a capable technologist (I mean, hey, I threw out some good buzz words), it wouldn't actually buy me much in terms of a real understanding of the risks, constraints, and goals that should drive the architecture. If the project did come to fruition, I'd quickly realize that my "design" had some serious holes, and I'd have to scramble to fill them in.
(As an aside, I think this is a common pitfall for developers. Although we like to fashion ourselves as "problem solvers", too often we live up to only the second half - we're just "solvers". The exact "problem" that we're addressing isn't always clear, well formed, or even real, because we were too quick to jump in with our own ideas and assumptions, instead of slowing down to first listen and understand.)
Nowadays, with a little more experience, I try (at least in these early conversations) to only ask questions, and hold off on proposing anything too early. If architecture is about the hard things, my goal is to hunt down what these things are. Only when I've mapped out the terrain do I try to map out a route forward.
For whatever it's worth, here are a few questions I start with:
- How many users (or consumers) are there, how much will they use it, and are there patterns (or spikes) to their usage?
- What devices would access the application with (e.g. mobile, desktop, voice, etc.)?
- What is the sensitivity or importance of the functionality or data that this system provides or exposes? For consumers, is authentication alone sufficient, or does access to certain pieces of the application need to be controlled or managed (i.e. access control)?
- Is any data persisted? If so, what type of data is this (structured, unstructured, etc.)? How much is there? How does the data get into the system (e.g. user entry, telemetry, etc.)? Is data created, read, updated, or deleted? How important is integrity or consistency?
- What other systems does this system need to interact or integrate with? What is the nature of the communication (e.g. real-time, batch feeds, etc.)? What type of security is necessary?
- On what hardware does the system run? Is it a kiosk, embedded system, server-based, etc.? Can it be hosted on a public cloud, or does it need to be managed internally? Who owns and manages the machines on which the system runs? How will it be deployed? How will updates be delivered?
- How critical is the application? Can any downtime be tolerated, and if so, when? What is the cost of downtime?
- Who will maintain the application when it's in production? What tools will they have available to monitor or verify the health of the system? Will they be able to
- What is the timeline for which the system needs to be built (or new features need to be delivered)? What is the development capacity?
In the end, this is software, and so there are innumerable facets, variables, and complexities to explore (and that could trip us up), and so there are plenty of other questions that might need to be asked. These are just some starting points, but where the conversation flows from there depends on the system.