a blog written by Brandon Mowat

Rewriting Matcha & Mochi

Sat Oct 03 2020

I started a blog in 2019 when I was at a point in time where I was trying to focus on being more present. As a step in that direction, I decided to create a blog as a place to think openly, vent, and share ideas – as opposed to posting to a platform that somebody else controls and the tools for self expression is limited. I'd heard about a new tool used for generating static HTML webpages with React called GatsbyJS and it felt like a great candidate for the job. Gatsby has a great library of different website templates to choose from including a Blog. "Fantastic!" I thought, so I cloned the project and I was up and running, but it wasn't quite as full-featured as I was looking for.

Motivation for Building a Better Experience

The basic writing experience on the Gatsby Starter Blog isn't terrible. It pulls from a directory containing the markdown of your blog posts and transpiles them into static HTML files that serve as the blog posts on your blog. Simple, no-fuss, and effective – everything you could want right out of the box, right? The only problem is that with this setup, all your posts need to be checked into git, and built. Sure, you could set up a build trigger to rebuild the static HTML on every commit but what happens when you're someone like me or you want to compose a new article from our iPad or iPhone? The GitHub app doesn't let you create new files so the Gatsby Starter Blog isn't a great option – the GitHub website lets you do this but it's a terrible experience when all you wanna do it add a new page. So naturally, I decided build my own solution.

Requirements

  • An iPad app to create new articles on
    • CRUD
    • Easy and enjoyable to write on
  • Database to store Articles
  • Web view for articles
    • must be rendered on the server for SEO

After the requirements planning, I got a little more specific with the architecture and how all of the different pieces would fit together. I sketched it all out in procreate, reviewed it, and it all seemed kosher. Next step was to put pen to paper – or more appropriately, fingers to keyboard (heh heh i am nerd 😎).

Mochi Architecture Design

ClojureServer

When deciding on technologies to use for a product, you should use a technology that you're familiar with and can build fast. On the contrary, when working on a personal project, that's the opportunity to learn a new skill. I hadn't yet built and deployed a project with Clojure but had been reading and learning a lot about it. So I dusted off a simple base project that I had hacked together while learning the basics, and we were off.

Check out ClojureServer here.

Mochi iOS

When it came to writing the iPad app for Mochi, I had very little experience with mobile development. I had worked with React Native while building Frrand (a story for another time) and had hacked on a small voice control app for my hue lights back in like 2016. SwiftUI was gaining a ton of popularity – my Twitter timeline was always full of tweets like, "LOOK at this cool interface that I built with 12 lines of code!!", so naturally I had to see what all the hype was about. As soon as I started dipping my toes into SwiftUI, the appeal became very clear – programmatic UI development is so much more natural to me. I'm not sure why that is; maybe it's because I come from a web development background where I'm writing JSX? Whatever the case, I'm into it.

Here's what the writing experience looks like in the iOS app at the time of publishing.

Mochi iOS app screenshot

Mochi Web

Building the web view for the blog was probably the most simple part of the whole process since the Gatsby team had basically done all the work for me. They make it really easy to specify where to pull the data from to create the static pages that will serve as your posts.

Below, is basically the only custom code that I needed

// gatsby-node.js

const axios = require('axios');

const get = endpoint =>
  axios.get(`https://brandon-server.herokuapp.com/${endpoint}`);

exports.createPages = async ({ actions: { createPage } }) => {
  const { data: articles } = await get('articles/');

  let publishedArticles = articles;

  // omit post if labeled a draft in production
  if (!(process.env.NODE_ENV === 'development')) {
    publishedArticles = publishedArticles.filter(
      article => article.isPublished
    );
  }

  // Create a page that lists all Articles
  createPage({
    path: '/',
    component: require.resolve('./src/templates/home.jsx'),
    context: { articles: publishedArticles },
  });

  // // Create a page for each Article
  publishedArticles.forEach(article => {
    createPage({
      path: `/article/${article.id}/`,
      component: require.resolve('./src/templates/blog-post.js'),
      context: { article },
    });
  });
};

The Other Nitty Gritty Stuff

The most difficult part of this project was probably fiddling with Heroku and the API for the blog. When I had written, what would become the base of the API for this project, ClojureServer, it was designed to build very simply and just spits out a .jar file at the end of the build process. However, Heroku doesn't seem to recognize clojure projects unless there exists a project.clj file in the root of the project. So my solution here was to simply leave an empty project.clj file and include a Procfile that specifies a custom build command.

web: cat target/BlogAPI-1.0.0-SNAPSHOT-standalone.jar > dist/BlogAPI-1.0.0-SNAPSHOT-standalone.jar && java -jar dist/BlogAPI-1.0.0-SNAPSHOT-standalone.jar

The command can probably be simplified a little but I'm lazy and I can't remember the exact reason that I move the /target/*.jar file to /dist/*.jar. I must have had a reason at the time...

Another bump that I ran into at the time was that mLab was deprecating it's integration with heroku. I had chosen mLab as my data store for my blog because of its simplicity, and that I had used it for small projects in the past. Soon after I had made significant progress on Mochi, I received a notification from Heroku that they would no longer be supporting their integration with mLab and I should migrate off of it. It's not as drastic as if they were shutting down their services completely, but is was enough of a spook that I didn't want to commit to it any further. Luckily I hadn't filled up my database in any meaningful way and the move off of the platform was painless. The decision to end the integration was likely a due to the fact that MongoDB had acquired mLab back in 2018, something that I was unaware of until they notified me that I was going to be totally fucked if I didn't do something. So naturally, I followed in mLabs footsteps and moved myself over to MongoDB Atlas as well. Luckily, Mongo Atlas is nearly just as easy to set up as mLab. Plus, the additional tools that it provides around monitoring make me wonder why i didn't just use it in the first place 🤔.

Conclusion

In the end, I was really happy with how the project turned out. It's something that I plan to continue using as an alternative to platforms like Facebook, Instagram, and TikTok.

Building your own blog from scratch is not something that everyone needs to do, but what it affords you is the experience and gratification of building something of your own relatively from scratch. I also believe that DIY-ing your own software tools affords you the experience of actually designing a piece of software from scratch. It's a skill that I think it really attractive to many employers, especially those from small companies and startups where their product is far from finished.

The entire project is a WIP and I'm thinking about open sourcing it for everyone to be able to enjoy! If you're interested, maybe tweet at me to pressure me to doing it sooner rather than later 😅. I've been known to procrastinate things like this.

Thanks for reading 💕


Written by Brandon Mowat who lives and works at Ada in Toronto -- building useful things. You should follow him on Twitter