It’s pretty easy to be the programmer-hipster and dismiss any new web technology as unfit for “real” work. But there’s something happening right now that I’m pretty excited about, and I think you should be too: building distributed applications is becoming accessible to hacks like me.
I only understood how misguided my attempts to stuff modern applications into a Rails-style structure when I started working on the architecture for Valet.io. We needed to expose most of our data in realtime via WebSockets. Trying to glue WebSockets functionality onto Express quickly fell apart. Handling HTTP requests and managing WebSockets clients don’t really have much in common—especially since our WebSockets API is designed to be consumed by browsers and our (unreleased) REST API is intended for server-side access. I had been trying to bake two server-side applications into one. Only when I split them into three services: an internal API, a WebSockets API, and an HTTP API, did I really progress on the application itself instead of forcing a framework to do something for which it was never intended.
Service-oriented architecture design is by no means new. Amazon’s religious adherence to product-oriented architecture birthed Amazon Web Services and enabled Amazon to grow into one of the world’s largest retailers. What has changed in recent years is 1) the proportion of non-enterprise web applications that could benefit significantly from SOA has grown dramatically and 2) the components for running, managing, and linking services have gotten dramatically cheaper, better, and easier to use.
While you as an individual developer or member of a small team are by no means Amazon, think of how many applications you’re really writing when you build a “single” app. Does your application run in the browser on something like Angular or Ember and transact with a back end API? Well there’s two applications. Have to request data on a scheduled interval? That’s another. An application that has a discrete front end, multiple end-user protocols, and uses a few external APIs ir probably composed of no fewer than half a dozen services.
You could probably successfully mash all that into a single application, but that doesn’t mean that’s the best choice, even if you’re the solo developer on the project. Say you bake your payments API calls into your main app. What happens if you want to switch payment processors? If your payments logic is in its own service, another developer can work exclusively on that service, deploy it when ready, and never touch the main codebase. New services can be written in any language, so you can choose to optimize for performance or development speed on a service level rather than on an application level.
Most startups start out expecting to need a total rewrite once they get any kind of serious traction. No design pattern will change the need for rewrites, but distributing functionality across well-contained services will allow you to repair individual bottlenecks as you discover them. Shoving a functional but hard-to-maintain product into the wild will hurt growth in the long run for anything but a very early MVP. A little advanced planning and ops will prevent a lot of time wasted in critical stages of product growth.
The tools that support this kind of architecture have advanced far enough in recent years that a developer with almost no low-level knowledge, normally content to let Heroku work its magic, can build distributed applications. ZeroMQ, an open-source messaging library, links the components of your application together. Docker, the container engine from DotCloud, lets you configure Linux containers and deploy them anywhere. You can spin up an exact copy of your production environment on your laptop.
Exposing this kind of power to inexperienced developers isn’t without costs. I know I’ve fumbled around quite a bit and let technical optimizations consume entire days that were supposed to be spent writing new features. But some amount of application design is healthy. An informed choice to build a traditional Rails app is fine if you’re building a product that uses technology (e-commerce, simple SaaS app, etc.) rather than a technology company. But if you’re building a modern web application where speed and flexibility are paramount—the future is service-oriented, and the time to start learning and building is now.