You might think this is one of those buzzword ‘list of nine things’ style posts, don’t switch-off just yet.
Nine is our next idea from our product studio Alt Labs. We first launched Payhere, a no-code tool that helps you unlock Stripe by giving you beautiful payments links and a storefront to sell your one-off, subscription and donation based payments.
After many requests and/or people bastardising Payhere to sell physical products, we’ve finally built Nine. In keeping with the same speed and simplicity of our other products, Nine lets you set up an online store with native subscriptions built right in. We believe it’s the easiest way to sell physical subscription products online, don’t take our word for it, try it and let us know!
For many years my backend language of choice has been Ruby on Rails, it’s what powers Payhere and 99% of the other client projects I’ve built in the last decade. I’m comfortable with it, fast with it and fairly proficient doing a test-first workflow using RSpec.
In the last couple of years things have been changing, we’re now embracing a serverless approach, picking more headless APIs and integrating them, rather than reinventing the wheel.
In the run up to building Nine I spent some time evaluating a few different options:
- Rails - stick with what I know
- Firebase/FaunaDB/Hasura - before going full-time on our own products, our last two clients used firebase for the backend
- Typescript/GraphQL - I've used typescript a bit with React and mostly enjoyed it and used node/express a bunch over the years for microservices or cloud functions
Having used both 1 and 2, I had to try setting up a project with Typescript, apollo server and type-orm – so I had something to compare against.
I would compare each of the major web frameworks in node to sinatra, whilst it gives you ultimate control, you have to set up a hell of a lot of components yourself. This is the part that has put me off the most.
- Need an ORM to save stuff to a database? Well, go and find one.
- Need to run async jobs for processing things or sending emails off the main thread, go find one.
- Oh and need to send those emails? Go find a mailer library or build your own.
I think the node community is really lacking a major web framework that does all the common jobs and has some elements of convention over configuration. Laravel and Rails can spoil you for just having all the major pieces you need to build a web application built-in.
One aspect of this experiment has been somewhat sticking to tools I know, in using a new framework and GraphQL for the first time, I wanted to stick to other tools that I have experience with and are more stable and boring.
I decided the best option was to use Postgres and found type-orm to be a solid choice, well maintained and used by plenty of others.
Setup was a breeze and the model definitions and automated migration generation has been a joy to work with so far. Add some fields to your model, tell typeorm to generate a new migration and it will write the up & down SQL for you.
Having type safety on all your database/entity code has given me huge confidence in the backend system so far, more on this when I touch on the frontend.
As I mentioned, this is my first time building a GraphQL service (I have used Gatsby a lot, so its a little familiar). This was also the first piece of kit that I was 100% settled on using, even if I did revert back to Rails.
As soon as I connected up the frontend and ran type-graphql which gens typescript types for all the data your backend provides and accepts in mutations, I was sold.
I don’t even feel the need to write frontend tests to get high confidence that things are working as they should be, I’m kind of treating typescript compiling as a given that I don't have any major issues.
To help mitigate any large traffic spikes from bogging down servers and to keep the TTFB low, I knew Nines frontend was going to be static.
The one thing I wasn’t sure on was having to re-deploy the full platform any time a single merchant added a product or changed their stores theme.
Luckily vercel and the Nextjs team have an epic new feature, Incremental Static Site Generation. This allows you to ship the pages you know about at build time, and have the others render on the fly (like SSR), but once rendered, be saved as a static page for any future visitors. You get the benefits of both worlds, blazing fast, infinitely scalable pages, and as up to date as if you used server-side rendering.
GraphQL inputs and queries are all typed, which means you can leverage awesome code generation libraries to take your GraphQL schema and create a bunch of typescript interfaces and even generate React hooks to query and mutate with all of these types automatically built in.
This is the icing on the cake for GraphQL, completely automated type safety right the way through from the database to the React components.
Frontends are deployed on vercel. For the backend, since I’m using a few new frameworks/libraries already I don’t want to introduce anything new here.
We’re using Heroku, because I know it well, it’s not some new fangled fancy kubernetes or lambda – but it easy, reliable and cost effective. And so far with Payhere, it hasn’t skipped a beat, and that’s something I can’t say about too many other hosts I’ve used in the past.
I managed to figure out the pain points – setting up mailers, background jobs (using bullmq) and found a nice ORM (typeorm).
The last piece of the puzzle which I have 80% working is an interactive repl to allow quick queries against production data. If anyone has suggestions for this please leave me a comment.
So far, I am delighted with all of the choices and Nine is almost ready for public launch. I continued on with the Typescript/GraphQL project and don’t have any regrets, yet.
There are also some other major benefits emerging, such as WAY lower memory usage vs. Rails, faster API responses and writing a lot less tests for the same amount of confidence when deploying.