
My Journey To A Modern, Unified Stack
I’ve been writing code for twenty years — I found this out, to my horror, when I discovered an old CD-ROM I’d kept from an issue of a PC Magazine, dated July 1998, which had a copy of Borland Delphi on it — and which had kicked off my interest in programming (after I had tinkered around with Turbo BASIC a year or so before this). In 2003 I taught myself PHP, using a book called ‘PHP in Easy Steps’, and by 2004 I was making money from it. By 2008 I was a full-time professional, and fully immersed in PHP, where I stayed firmly until last year.
PHP has changed a lot over the years, and thanks to modern frameworks like Laravel and the large-scale work done by the likes of Facebook and Wikipedia it is now a professional, object-oriented, testable, modern programming language with a thriving community. It still struggles to shake off the bad name it gained over the years , thanks in no small part to the plethora of awful Wordpress plugins and themes. PHP has been a victim of its own accessibility. Anyone can write PHP, and they do.
Over the past three years or so, I have been happily creating large-scale projects in Laravel, and deploying them on EC2 instances in Amazon Web Services, with load-balancers, external database servers, external cache servers and all of the goodness that comes with a modern PHP application stack, and found the whole process productive and robust. But then a few things changed.
One of the things that makes traditional web applications so darn hard to keep robust, reliable and secure, is the need to manage the machine(s) that it runs on. Patching the operating system, the web server software, the database software, the caching software, and any dependencies your application has is a full time job, even for an average web application. It would be amazing if all you needed to worry about was your application code!
Then we have the scaling thing. When an application needs to scale, it usually means vertical (beefier machine) scaling, or horizontal (more machines) scaling. Vertical scaling is easier to handle in application code. In fact you just don’t need to handle it. But it isn’t practical for any real scalability beyond a single enterprise. Horizontal scaling requires very careful architecture design, and meticulous attention to detail to get right. Into the bargain, it requires a delicate orchestra of hardware and software services all playing nice together, and being managed, monitored and secured with air-traffic-control style precision. That’s fine, we’ve mastered that. But the annoying thing is that this kind of scale, even with ‘elastic’ cloud services like AWS, usually means that resources are burning away cash for hours at a time when they aren’t required. Enter, serverless.
I first became aware of the concept of a serverless architecture in the autumn of 2016, and I tinkered around with Amazon’s Lambda service a little bit. It’s a powerful concept, and requires you to adjust your thinking a little. In a nutshell, the service provider (Amazon) is running a fleet of machines, which run a particular ‘runtime’ — for example C# or NodeJS. Instead of renting a machine by the hour, you simply run your code on a slice of one of these machines for a few (milli)seconds at a time as it’s required, and pay by the second — not the hour. So if your app is busy between 9am and 12pm, and quieter in the afternoon, and completely unused overnight, the server will only be ‘running’ when users are demanding access — therefore, you aren’t paying for unnecessary resources. Moreover; due to the ephemeral nature of the container-style architecture, and the scale of the ‘serverless’ fleet of servers, scalability becomes trivial, as long as you design your application correctly. Multiple instances of your application code can be executed concurrently, limited mainly by administrative throttles.
In building my applications in AWS Lambda, I chose to use NodeJS, as I was familiar with Javascript, having written lots of it (badly) to supplement my PHP over the years. I quickly got up to speed, helped along by a few colleagues who had much more experience of modern ES6-style Javascript — and I fell in love with it.
By the beginning of this year, I was completely convinced that Javascript microservices were the way to go in developing any application that needs to scale, and it was around this time I started working with ReactJS. React is a JS framework, created by Facebook, which allows developers to compose an application screen using components, and follow a more object-oriented style approach to development — as well as providing a mechanism to manage state; which has always been tricky. Better than that, React has a younger cousin called React Native, which follows the same paradigm, and similar syntax to React, but instead of compiling to JS, it compiles to native iOS or Android UI components which can be distributed as native apps for those platforms.
In February, I took the opportunity to start my own business, and Relative Limited was born. To begin with, I was a software contractor, providing my services to companies who wanted a developer for a short period of time. I also had the opportunity to work on some of my own projects — and for these, I chose to work exclusively in NodeJS with AWS Lambda, and React/React Native.
In the summer, the opportunity to expand the business came along, and I opened our office in my home town, and employed the first member of staff.
Most software houses have a chosen platform, language, paradigm etc… and I’ve worked my entire life with a LAMP (Linux, Apache, MySQL, PHP) stack. I’ve recently had the opportunity to work at a company who use Windows, C#, React and TypeScript, and over the past couple of years I’ve worked with NodeJS and Amazon Web Services. In taking the leap and making Relative a ‘real’ software company, I chose to adopt a unified stack for all projects, and a modern development methodology that maximises productivity, scalability, efficiency and testability.
One thing that changed my life, professionally, was reading ‘Clean Code’ by Robert C. Martin (Uncle Bob), and forming Relative came at a time when my experience of NodeJS, React, AWS Lambda, TypeScript, Unit Testing and Clean Code were all converging at once in my mind, and I took the leap and ditched PHP from my toolbox. Not because PHP is bad, but because it didn’t fit.
At Relative, we have adopted Modern Javascript as our house language, but more specifically, we use TypeScript. This plugs a lot of little holes in Javascript and gives us a nice rigid language framework. Next, we write all of our front end (web and mobile) with ReactJS or ReactNative, respectively. We write React in TypeScript too. Backend services are all written as microservices, using the Serverless framework, running on AWS Lambda, and again written in TypeScript (NodeJS).
The biggest commitment we’ve made is to Continuous Deployment and TDD (Test-Driven-Development). All of our code is written using TDD (we use Mocha, Chai, Enzyme) and we use BitBucket Pipelines to build, test and deploy our code. We also use AWS CloudFormation to manage all of our infrastructure in code, so we never need to poke around in the console! This is time-consuming, but has massive benefits for the long term and has already paid dividends. Most of the time, we use pair-programming, but occasionally we work alone, and in these instances we have a strict Peer-Review policy. The build must pass, and the code must have been reviewed before it can be merged.
Finally, having worked with MySQL for 15 years, all of the projects (so far) at Relative have been back-ended by another set of new tools in my arsenal — NoSQL databases. Right now we are using DynamoDB in our client work, and MongoDB for some of our own projects. The difference is primarily down to the differing data structure needs of the projects — MongoDB works better when we need lots of nested documents, and DynamoDB for flatter structures. We haven’t put Mongo under any strain yet, but with Dynamo we’ve done some pretty rigorous load tests, and got to know exactly how to scale it — and it works very well.
I wanted to wrap this up by saying that I’ve never been one for jumping on the newest and shiniest technologies — as you’ll notice from my career-long PHP bias, but the shift en-masse to this new combined stack has worked really well, and I’m looking forward to seeing what else we can do with it. I do foresee that we’ll be back in the land of relational databases before the year’s out, as there will always be a need for this, but right now I don’t foresee a move back to PHP for the work we do. The simplicity of being able to write server-side, browser-side, and mobile-native code with one set of tools has been a game changer, and we are just getting started.

