Assignment 6: Application Architecture
Monday, October 4th at 8am
Before you get started writing code, you need to make some decisions about the overall architecture of your app and what technologies to use. These decisions should be made thoughtfully. Much work will be done atop these foundational choices. It is usually quite difficult, not to mention wasteful of time and effort, to change your mind about such things later.
A few common examples of architecturally significant decisions include:
- Where and how to store data
- Which programming language(s) to use
- Which framework or major library to use
It can be challenging to know how to make these decisions. To provide some helpful structure, you will be creating architecture decision records, or ADRs. There are various kinds of ADR “schemas”, but we will use a lightweight one described below.
These ADRs, and this assignment’s deadline, are useful as “forcing functions” to make these kinds of decisions early so that other work can begin. But they are also helpful records to refer back to later. It’s not uncommon to make a choice at one point, then regret that choice on a steep part of its learning curve and be tempted to switch. Not that switching is always a bad idea, but it’s definitely not something to be done lightly, and having a written rationale for that choice can serve to remind you of the benefits of the original choice.
First, list the significant architectural decisions you will need to make for your app. See “Hints” below for ideas.
Note that ADRs are intended for strategic rather than tactical things. You don’t need an ADR for which test runner library to use, for example. (Although it can be valuable to capture a rationale for your choice in the corresponding git commit message, as described here.)
As a general rule, somewhere between 3 and 6 decisions is probably sufficient.
Then, for each decision, create an ADR with the following format.
Summary - A summary statement, in the form, “In order to <goal>, we decided to <decision>.” For example, “In order to store data persistently, we decided to use PostgreSQL.” I recommend writing this section last.
Problem - What problem do you need to solve? Describe the context of the problem. Why is it a problem? Why is it important to solve? Imagine writing to a classmate on another team. What would you need to tell them for them to understand the problem?
Constraints - Are there any kinds of possible solutions that are out of bounds for this project? For example, if the client isn’t willing to pay for a solution, that’s worth noting. Or perhaps solutions that only work on MacOS aren’t something the whole team can work with. Capture the constraints, as well as the reason for the constraints, here. Also capture any assumptions you’re making about what the client might want or not want.
Options - Which candidate solutions are you evaluating? List pros and cons for each one.
Rationale - Which option did you choose? Why?
Post your complete application architecture on your project web site.
Here are a few common examples of significant architectural decisions that should have an ADR describing the decision. Many of these decisions could be made more than once for different components of the system, e.g. the frontend vs. the backend.
- Which programming language should we use?
- Should we use a framework? If so, which one?
- Should we use a backend service (e.g. Firebase, Parse) or write our own?
- Where should our backend service be deployed to (e.g. Heroku, AWS, Azure)?
- Which database should we use?
I also welcome (but don’t require) ADRs for processes rather than architectures. Perhaps we could call those PDRs. A prominent example of a significant process decision would be which git branching style to use, e.g. 1, 2, or (my favorite) 3.