The Blog

page 3 of 3
Architecture

The Reversible Jacket Pattern

TL;DR: Reversible Jacket is a useful pattern for developing a web frontend UI and backend API simultaneously, and here’s a demo.

Tools like esbuild and Vite make developing static frontend web applications enjoyable, and there are tons of starter templates out there for them. But if your frontend UI and backend API are being developed together as two tightly-coupled halves of a monolith, how do you structure your project to handle both the development phase and the production phase without tearing your hair out?

Voilà: the Reversible Jacket. The idea is that the frontend dev server proxies API routes to the backend server during development, while in production the roles are reversed and the backend hosts the frontend’s static assets and the API routes as single-origin app. The README explains why that’s a good thing and how this reference implementation works. This could be useful for anyone making a Jamstack app using the BFF pattern, regardless of their specific tech stack.1 In my experience, a Reversible Jacket codebase is a pleasant and productive workspace once configured.

This is nothing revolutionary. Maybe this pattern is so obvious that nobody bothered to write it down, or it is already named something I’m oblivious to.2 If not, I think that “Reversible Jacket” is descriptive and memorable. Here are some tools I found that solve similar problems:

All I’m trying to say is that there seems to be some momentum for this kind of smooth local development experience. Those proprietary tools above might not be much help to a UI/API destined for a platform like Kubernetes, ECS, GCR, Fly.io, Render, etc. We owe it to ourselves and the maintainers that will eventually inherit our codebases to invest in good DX.

Footnotes

  1. Or, this could be the final thing that sends you screaming into the arms of Hotwire or Phoenix.

  2. That would be embarrassing, but I would like to know if so. Please reach out.

Astro

Astro

One of my reasons for having a personal website is to have a place to experiment with technology. I’ve been using VuePress for a while even though it’s more of a documentation tool than a personal blogging tool. Last year I upgraded VuePress from v1 to v2, and this year I had my eye on VitePress. I began the migration but then the Astro project caught my attention. As you can see from this post, I’ve moved my personal site over from VuePress to Astro.

I think that VuePress and VitePress are probably not the the right tools for what I’m specifically trying to do. If the goal is simply to put some markdown files on the web, then just about any SSG is fine. Astro is a little bit closer to Nuxt or SvelteKit though, and I appreciate what they’re trying to do.

Here are a few things I learned migrating from VuePress to Astro and Tailwind:

  • You can embed components in Astro’s markdown, you just have to import the component in the frontmatter.
  • Instead of wrapping non-SSR components with <ClientOnly> tags, Astro uses a directive. It would look something like this: <YourComponent client:only />
  • Both Astro and VuePress choose some markdown extensions, but VP gives more out of the box. For example, to enable emoji shortcodes (:+1: = 👍) I had to install and configure remark-gemoji.
  • Local search is not not included like it is with VP. I don’t miss it, but it could be a dealbreaker for some.
  • There doesn’t seem to be an easy way to restore VuePress’s custom containers. Maybe I overused them.
  • If you used a lot of inline code and now you’re using Tailwind typography, you have to override the part where it helpfully adds graves back in. Otherwise all of your inline code will look `like this`.
  • I got caught on a known issue (#2146) about embedding fonts from npm packages, but there’s a workaround.

Here’s the astro.config.mjs that worked for me (see update for more recent version):

import { defineConfig } from "astro/config";
import vue from "@astrojs/vue";

export default defineConfig({
  buildOptions: {
    site: "https://barnabas.me",
  },
  integrations: [vue()],
  markdownOptions: {
    render: [
      "@astrojs/markdown-remark",
      {
        remarkPlugins: ["remark-gfm", "remark-smartypants", "remark-gemoji"],
        rehypePlugins: ["rehype-slug"],
      },
    ],
  },
});

Switching platforms is kind of like moving house. It forces you to take stock of what you have and clear out junk you don’t really need. If it’s still in the box 📦 since the last time you moved, maybe it’s time to throw it out. 🗑️

Infra

Fly.io

I just updated my DBaaS article with a new entry: Fly.io. They caught my attention a couple days ago via HN. I really like what they’re doing and wish them the best.

I updated my calculator code with their pricing and was shocked how much they undercut everyone. Then after I found and fixed a bug, they settled in to a more reasonable spot. Still, they now offer a generous free tier that they’re rightly proud of.

Fly.io’s CEO Kurt Mackey replied to the question “are you running your own servers?” in that HN discussion:

We run our own servers. It took a lot of work but it’s really making life easier now. I’m not sure we could offer a free tier like this on top of another cloud.

In fact, some of the other PostgreSQL DBaaS providers offer a free tier but do not run their own servers. How and why do they do it? I think that would be the 80/20 rule or Pareto principle in action. I’m guessing that they must subsidize all the free accounts on the low end with the big spenders trapped into overpaying at the high end. It brings to mind the image of whales being harpooned in a cove.

VuePress

VuePress v2

I just upgraded my personal site from VuePress v1 to v2. Some things were very easy, some were not. Here are some of the things I learned from this project:

Once VuePress v2 is out of beta there’s a number of documentation sites at work we’ll probably want to migrate. I wanted to know how big a job that will be, so I used this site as a test. There are still some rough edges, as evidenced by this bug I found while upgrading (update: fixed in 2.0.0-beta.26). If you are interested, here’s the PR for this upgrade.

Hardware

Macbook Hard Drive Reset

The other week my MacBook Pro’s hard disk died. Even though it was one day past warranty, the Apple Store technician was kind enough to fix it free of charge. I learned the following things through this experience:

  1. If you pay for your own Apple hardware (as in, not under the protection of an IT department), you have no choice but to purchase AppleCare. “Ah but I do have a choice,” you say, “or why would they let me decline coverage?” True. You also have the choice to cover yourself in Worcestershire sauce and swim in a tank of piranhas.
  2. The cost to you to replace a 512 GB hard disk for a 2017 MacBook Pro is $740 + 1 week of No Laptop. The cost to your spouse is arguably much higher, if you are the complainy type.
  3. Apple Stores’ pandemic protocol is very good: plexiglass, limited customers allowed inside, constant surface wiping.
  4. Being inside a nearly empty Apple Store is eerie and sad. The music doesn’t help.
  5. Having all of your code in source control and your files in the cloud is not the same thing as having your computer properly backed up.
  6. An iPad is no substitute for a laptop. Not even close.
  7. Hardware problems can really sour one’s mood.
  8. Even if you tell the technician that you want macOS Catalina not Big Sur, you should double-check that they didn’t helpfully install Big Sur anyway.
  9. To downgrade macOS, you’ll need a blank USB flash drive, these instructions, and an abundance of calm serenity.
  10. Modern software and hardware is simultaneously an astonishing miracle and also the worst thing ever.
Infra

Render PaaS

While reading about DigitalOcean’s new App Platform, I stumbled across a cool new PaaS called Render. They launched in 2019 and offer a compelling alternative to Heroku. I just added them to my DBaaS Calculator.

They’re the only option in my calculator under $10/month, which is a big deal when you’re just starting up a proof-of-concept side project. It’s true you can get a shared DB from ElephantSQL for $5, as long as you don’t need PostGIS. Anyways I hope Render gives Heroku a run for their money.

Writing

Memory Article

Last week I repeatedly had a sense of déjà vu, especially whenever I would begin a new email or text message. It happened frequently enough that I began to worry if I was losing my memory. So, I started writing a blog post about how vital a good memory is, but before I knew it I had written far too much. So I put it in a separate article and then I kept fussing with it for too long.

But then I remembered that articles are meant to be updated continuously, so out it goes. Now I just have to remember to update it later.

Meta

Blog Restart

With this post, I’m restarting my blog. Maybe the “articles” format was too ambitious and keeping me from writing more often. At least, that’s the most self-sparing explanation. I say “restart” because I’ve blogged before on Wordpress and Tumblr, but not recently.

Technically speaking, I enabled a Vuepress plugin and embedded this blog into the existing site. If you’re interested, the source for this site is public, and the configuration to make this work is mostly in docs/.vuepress/config.js.

Personally speaking, I’m glad to have a place to journal again. I’m also thankful my only recurring cost is the annual domain name renewal.

Meta

Test Post

This is a first test page, the “hello world”.

There is more here, but it’s not part of the excerpt.