Optimise for simple web apps and complex systems separately
How to make easy things really easy, and hard things pretty easy too
Generic solutions always seem like the answer (what’s the question?). I don’t know if it’s a software engineer thing, or a human thing, but there’s something obviously appealing about building a solution that fits all possible problems elegantly. Given a hammer, there’s a lot of satisfaction in seeing how to apply it to all sorts of innapropriate nails.
The problem is: custom, specific solutions are often much better for many tasks. Eventually, maybe, we’ll get rid of native apps and write everything in HTML (or vice versa!). But HTML has a long way to go, and I’m not even sure it’s a good idea for it to try to get there. C is a fantastic language for writing system tools, but it’s not going to replace perl anytime soon for text processing: and I’m not sure it’s a good idea for it to try.
Which brings us to Container Orchestrators and Platforms as a Service (What I’ve started calling “Containerless Development Platforms” because PaaS is a terrible word). There’s an appeal in taking a generic Container Orchestrator (Kubernetes, Docker Swarm, Mesos etc) that scales all the way to a complex distributed system and using it for simple web apps too. But is that a good idea? I think no.
The difference between simple web apps and complex services
Simple web apps are simple! They consume services (normally a very small number, maybe a database and a message queue) and reply with web pages. Sometimes they talk to other simple web apps. To scale them, you run more instances. To roll out a new version you create some instances with the new code and swap the route over. You can treat them in an extremely standard, simple way.
Complex services — things like a highly available database, a distributed message queue, a large microservices-based app — are not simple at all. Each one needs it’s own way to be upgraded, needs to consider backup, service discovery, needs to consider build tools and packaging and so on. You end up with a lot of platform complexity to make them simple enough to run. Which is fine: if you need it.
Options for Complex Services
There are great options for complex services: Kubernetes, Docker Swarm, Cloud Foundry Bosh, Mesos for example.
If you need to run your own complex services (as opposed to using a platform-provided database service, for example) it’s a good idea to pick a system that has enough complexity for what you need, but not too much more. You don’t want to be driving down the street in a tank just because one day you might need to drive through a wall.
Options for Simple Web Apps
Simple web apps should use simple infrastructure. Don’t try to use something that can scale to the most complex apps or you might find yourself buying the complexity needed by those apps. When you move from one app to another, you should know it works the same way as any other app in the platform: over-flexibility is the enemy of simplicity.
If you can, new systems like Glitch let you write an entire app in the browser with extremely minimal startup times. Or, platforms-as-a-service like Cloud Foundry (which has many public hosted versions you can set up an account with within an hour) or Heroku can let you bind services and deploy simple web apps extremely quickly and repeatably.
The Trick: Most things should be Simple Web Apps!
I’m constantly amazed how often we reach for complex solutions when simple solutions work. The vast majority of apps being built today can and should be simple web apps, yet we often find ourselves building them as if they have all the necessary complexity of the most complex app being built inside Google or Facebook. They don’t, most of the time we’re building simple systems, and a simple tool should be able to let us iterate faster and deliver quicker.
Making easy things *really* easy (and hard things pretty easy too).
It’s great that new systems like Kubernetes and Consul and Etcd and Zookeeper are making incredibly hard things more and more practical to build. But 90% of apps aren’t hard things! Their complexity is in their UX, their market fit, how quickly they deploy new features — not their computer science. We have great tools for the 10% of apps that are necessarily complex in our toolbox now, we should our spend time optimising for the 90% that aren’t. Focus on simple platforms and simple apps.