no blockers ✎

about

Monitor Books #2: an architectural mistake

This is part of a series of articles on what I learned from making a website for Monitor - a publication platform for poetry, innovative writing and criticism based in Manchester. This post details an architectural mistake I made whilst developing the site. To read the first post about how I started developing the site click here.

The Monitor site currently didn’t have a data source. There was only one book on the site so the content related to it was hardcoded in place. At the request of the client I had to add another book which meant it made sense to make a list of the two books and to loop over that and have data for each book fill a template page.

For a first pass I had initially stored the data for the pages of the site in JSON as part of the source code. Everything I had learned about web development told me this was a bad idea - as the website grew so too would the JSON and I would be shipping the entire database of products to the user’s browser to iterate over when the first landed on the site. Also my long term plan was to hand over control of the the copy/content of the site to the client so I didn’t have to be involved whenever they wanted some content changing on the site. This wouldn’t be possible with the current architecture.

I had go at new job a few months before starting this work and we used Redux for state management in our production React app. I was struggling to get my head around how it worked so I thought it would be a good idea to use it in the Monitor project to understand it a bit better. Adding Redux to the site would be killing two birds with one stone - learning Redux and adding state management and a data store to the app.

I also wanted to give serverless functions a try as with Netlify they looked really easy to use and I wanted to understand how they worked, their benefits and drawbacks. So I decided that my app should fetch it’s data using serverless functions and store that data, along with basket-related state in Redux. This was a bad idea.

Why was this a bad idea? The way the app was architected required the data to be pulled in from the external source via serverless functions before it could create the routes. So when a user hit any path (other than the root) they would see a 404 page before the app could pull in the data required to render the page. Fortunately the data being pulled in was a tiny json with the content for the two book pages on so even on a slow internet connection should only take a few seconds - still it was a suboptimal user experience and showed to anyone who visited the site my mistake. This approach also meant that search engines couldn’t index the site and that links on social media wouldn’t show a snippet of the page which encourages more people to visit the site.

  • user is linked from url

    🔗
  • browser initialises the React app site

  • app fetches data from serverless function

    ☎️
  • app creates routes from fetched data

    ⚙️
  • page loads

    🙌

🤦 the user sees a 404 this whole time 🤦

Another reason this architecture was a mistake was because I was designing for requirements that were yet to exist. The approach of having the data in a JSON in the codebase was a better approach because although it wouldn’t scale it was a better solution to what the client needed from the website at that time. They didn’t mind not being able to edit the content on the site themselves for now. Also whilst there were only two products on the site the size of the JSON didn’t have a drastic effect on bundle size. There probably isn’t a tutorial that would advise this approach but it was definitely a better approach than what I went for in the end.

One more reason that this architecture wasn’t a good idea - I was confusing the application state with the content needed to create the site. The product data - the copy, images, prices etc on each product page had no reason to be in Redux, they are simply the content necessary to render the site and that information is stateless - it doesn’t change depending on how the user interacts with the page. Redux is useful for state management and although it can be useful for storing information fetched from APIs it doesn’t really make sense to store the main content of the site in the Redux store. The basket and checkout functionality was all I needed to use Redux for as this changes depending on how the user interacts with the site.

So if this was a bad decision why don’t I regret it? Well part of the reason I chose to use Redux was so I could better learn Redux and implementing it taught me a lot of things that I found really useful at work. Also despite the approach to storing data for the routes not being a great fit the basket and checkout functionality that I built with Redux worked great! As well as this I learned a hard lesson about the limitations of React, this isn’t a mistake I will be making twice. It taught me to be think hard about what architecture I need for the project in hand given the requirements from the client.