Architecture
In the previous articles I've presented the main idea for our team's project and the requirements for our MVP. Now that we had a list of features that we all agreed on, we could start thinking about the general architecture of the project.
Keep in mind that this was the first time we've embarked on building a more complex web app, and we weren't really sure what kind of architecture or tech stack to use. In the enormous world of web development, it seemed like there were hundreds of frameworks and tools that we could use to get the job done. Feeling a bit lost among the huge list of available options, we decided to ask for help.
While I was studying at LaunchSchool, Eamon, one of the core curriculum graduates, and his team launched a very impressive web application for language learning called Alexandria (here is a link to the app if you're curious https://tryalexandria.com and here is a link to the case study that they wrote https://alexandria-reader.github.io). All of us knew Eamon and the impressive app that he built with his team, so we decided to ask him for some guidance in creating our own portfolio project.
Antonina set up a meeting with him and we started his 'interrogation' on the ins and out's of how he and his team built Alexandria.
Getting the chance to talk with an experienced developer is an invaluable experience. We talked at length about the different tools they used for their project, how they structured their work and the challenges they had to overcome. I was very curious on how they designed Alexandria's architecture and I got the answer I was looking for: Service Oriented Architecture.
In the context of our app, using an adapted form of this type of architecture made sense. We would split the application into three layers:
- Controller Layer This is the first layer. It receives HTTP requests and calls the appropriate service.
- Services Layer The second layer. Holds the logic and data processing required.
- Data Access Layer The third layer. Accesses and edits data on the database as needed. As an example on how this type of architecture would work, let's say that a user wants to create a new 'Neighborhood'. They would make a POST request with the data required to an established route, '/neighborhoods':
The request is received at the controller layer and the appropriate logic is called from the services layer.
-
The services layer then calls the Data Access Layer in order to execute the required actions on the database.
In this case the Data Access Layer is handled by an ORM (Prisma) which I will talk about a bit later, but the whole process is extremely simple!
What I loved most about this way of structuring the app was its simplicity and the well defined separation of concerns. It also makes the codebase easier to work with since each layer handles a very specific part of the application.
One more piece of the puzzle was now in place! We had a list of features and a general idea for the MVP and now we also had somewhat of a plan for the architecture. What we needed to do next was to establish the tools that we would work with. We had a few criteria required for selecting them:- It had to be genuinely useful for building our app;
- It had to be in-demand in the current market;
- Was in some way related to what we already knew. (For example, all of us had a deep understanding of JavaScript, so learning TypeScript wouldn't take too much effort).
Armed with this set of requirements we started a team debate and after going back and forth analyzing the advantages and drawbacks of each tool and we decided on the following (this is a glimpse of the reasoning behind our choices, in reality it took us longer to decide and we had to do quite a bit of research):
The Database
The main decision that we had to make in this case was if we should use a relational based database system like PSQL or one of the document based systems such as MongoDB.
During LaunchSchool, we all learned PSQL, so that was a big plus and since most of the advantages of a document based database where not really critical for our app (https://www.mongodb.com/nosql-explained/nosql-vs-sql) we decided to stick with PSQL.
Alongside PSQL we've decided to also implement something that none of us had previous experience with, but I thought that will save us a lot of time in the long run: an ORM, Prisma to be more specific. I won't get into too much details here, but an ORM is a system that translates between data representations used by databases to those used in object oriented programming.
The Backend
As I mentioned earlier, all of us already knew JavaScript, but we've decided that this would be a good opportunity to try out TypeScript and static typing. We considered that it will be helpful in catching errors earlier. Seeing that it was also a in-demand skill made it an even more attractive choice.
Express.js was the framework of choice for our API. Everybody on the team knew it and we considered that it will be a good option for the demands of our application.
The Frontend
I had worked on a few small projects with React and was enthusiastic to use it. I have to admit that in taking this decision we didn't take into account other libraries, it was either React or pure JavaScript and to be honest I don't ever want to work with pure JavaScript in making an interactive UI. I prefer Rect's component based system.
For future projects I would be interesting in trying out other libraries or frameworks, but in this case we just sticked with React and TypeScript.
Structuring our work
Now that we had all the pieces together we could finally start working, or so I thought. The fact remained that we should work as a team even though we were separated geographically and were on different time zones.
I knew we needed to work with Git & Github, but I wasn't sure exactly how to do it. After some time spent Googling and researching we established some basic rules regarding our project on Github.
1. We will never work directly on the main branch;
2. We will use branches for every feature we want to implement;
3. Every PR will need at least 2 reviews from other team members in order to be merged.
Git & Github are both complex topics that are easy to overlook. During the development of this project I dramatically increased my knowledge, but at the same time I realize that I still have a lot to learn regarding version management. I would advise any new developer to spend more time studying these tools as they are mandatory for working within a team.
First Mistake
Now I want to talk about what I consider to be our first mistake. Early on we established that it would be best to first start with the backend and the database and only then work on the frontend.
We wrote the requirements for our API and created diagrams for the Database and the API routes, but later I realized that even though we tried our best to plan everything, when we eventually started working on the frontend we realized that we've left plenty of gaps in the API.
That led to a lot of backtracking trying to fix or add modules to the backend.
What we should of done instead is to apply the philosophy of Iterative and incremental development. Decide on a small feature, and implement it on both the backend and frontend. Looking back, I think the development process would of went much smoother if we applied this concept. It would of allowed us to make sure a feature works on both the backend and frontend before advancing further. I've learned my lesson and in future projects I will do things differently.
I plan to stop here, since this article is getting a bit too long. I hope you've learned something interesting and stay tuned for the next article in the series where I will talking about our database and how we used Docker containers!
Helpful Links
I'm not affiliated with any of the links below. These are just resources that I genuinely consider useful.
Git & Github Collaboration - https://www.freecodecamp.org/news/how-to-use-git-and-github-in-a-team-like-a-pro/ (The best article I could find on the topic)
Iterative and Incremental Development - https://en.wikipedia.org/wiki/Iterative_and_incremental_development
ORM (Prisma) - https://www.prisma.io/dataguide/types/relational/what-is-an-orm#:~:text=An%20ORM%2C%20or%20Object%20Relational,used%20in%20object%2Doriented%20programming
Top comments (0)