A couple of months ago, we took a look at our use of vue.js to build the Narrandum app (and, indeed, the website you're reading this article on). Deciding on Vue was critical to making Narrandum the fastest, smoothest way to create customer journey maps and service blueprints. But there's more to making a delightful user experience than just the front-end user interface. In the end, any digital service is only as strong as the weakest link in the chain of systems which comprise it. To achieve the level of quality we needed, we had to be just as choosy about the bits of the service you don't see.
This is what led to us going for feathers.js as our middleware layer.
Well, that and our founder being more-or-less completely clueless. For a guy with no idea what he's doing, he's somehow accidentally made some pretty good choices for our tech stack.
Let's take a look at what makes feathers.js such a crucial part of our toolkit.
It cannot be emphasised enough that at the beginning of this project, our founder was just bumbling around in the dark. He'd try something, reach the limits of either its capabilities or his own, then try something else. Like an AI robot learning to walk, slowly but surely this random flailing resulted in a little positive progress towards the key goals of the project:
- Silky-smooth user experience – Narrandum is aimed primarily at designers, and they're a fussy bunch. It needs to be beautiful to use or they simply won't like it.
- Collaboration – Narrandum was envisaged from day one as a tool for teams to use together, whether they're co-located or working remotely. This meant building it for realtime collaboration and sharing of work. Depending on the tech stack, this could either be very tricky to implement, or virtually no effort at all, so it was important to choose carefully.
- Flexibility – Although there was a vision of what Narrandum was going to be, the details were very much up for discussion. User needs were our guide, and although we wanted to be as true as possible to the original concept, the only thing certain was that it wouldn't end up like we first imagined. So the framework underpinning it needed to be able to grow and change easily.
- Modularity – Although we were aiming for a cutting-edge experience that would give us a competitive advantage, we also didn't want to go up any technological blind alleys. So if, for example, we found ourselves needing to migrate to a different database, we could do so without having to rewrite everything from top to bottom. The ability to swap tools in and out of the stack was a high priority.
Unfortunately the story of how we discovered feathers.js is lost in the mists of time. But what we do remember is how appealing it sounded. It promised it could happily act as an intermediary between any frontend and practically any database. It charmed us with the lure of neat and tidy service-based APIs. It seduced us with sweet talk of easy implementation of realtime functionality. And best of all for our clueless founder, it seemed like it was pretty easy to set up and use. "Build prototypes in minutes and production-ready apps in days", they said. Sounds like everything we're dreaming of.
What makes Feathers.js so nifty?
patch to do what you need to do.
Hooks are a really neat way to shape your queries and data. When a request arrives at your server, Feathers can insert a hook right before it executes it, or right after it's prepared the response. Let's say, for example, that you want to restrict some data so that only certain users are allowed to see it – a very common scenario which turns up all over the place in Narrandum and countless other digital services. Feathers.js hooks make this a breeze – just include a "before" hook which checks the user has permission. Similarly, if you want to hold certain fields back from some users, you can use an "after" hook to strip them out of the response before it's sent to the client. Dozens of hooks already exist for common patterns, and of course you can make your own too.
Channels are great for realtime functonality. We always knew we wanted Narrandum to be a collaborative experience (originally aimed at teams working in the same room, but times have changed...). It was important to us that when one user updates a story, the changes are instantly shared with everyone else who's working on it. Feathers.js makes this simple with its channel functionality. You can create as many channels as you want, then add users to those channels, so that only people in the channel receive the data passed around within it. This makes, for example, setting up chatrooms extremely easy, but we've found other uses for it, such as notifying other users when someone is editing something shared with them.
It encourages good practices. Feathers is agnostic when it needs to be, such as your choice of database or front end. It will merrily figure out how to act as an intermediary for more or less whatever you're using. But when it comes to how the messaging is to be done, it's rather more opinionated, in a good way. Its services keep things nice and clean and lead to code that's straightforward to read and maintain. Not only will you thank yourself for choosing Feathers when you come back to stuff you wrote months ago, but so will whoever inherits your code after you. No obscure libraries, no opaque syntax – just concise, consistent queries that require minimal expertise to understand.
You can probably tell by now that we're fans. Feathers has more than met our needs up to now, and we're confident it will continue to do so as our dinky little setup becomes a globe-straddling behemoth that brings servers to its knees. We've got plenty more to chuck at it, and we're looking forward to seeing how it goes.