From a monolith to micro-services (part 1)

Giles Williams
Urban Massage Product
2 min readMar 27, 2015

When writing the first version of Urban Massage, we followed the standard agile approach when starting a new project — build a big app that can do everything you need — but at the same time make sure that you encapsulate in a way that you can easily split out each concept into a separate module / API / service at a later date.

As we scale faster and faster, maintaining a monolith is obviously not an option —I’ll be speaking in more depth in a later posts about how we go about refactoring in practice, but in the meantime here are some rules we chose to follow along the way.

Rules of the road

  • No more than one service can mutate a database table (and any other ‘collection’ concept such as in NoSQL DBs)
  • Each service should not store more than 7 entities (so you can keep all of the ideas in your short term memory at once)
  • Every service should expose a JSON API (even if it’s a background queue-based processor it should expose a stats / uptime route)
  • Following on from the above — every service must expose an ‘up’ route — this makes instance rotation at your load balancer much easier
  • All services should contain an ‘organisation’ concept — this way your dev environment becomes much simpler as you can have a shared ‘sandbox’ version of each service — and everybody’s dev machine (as well as your test / staging environments) can just use a different ‘organisation’ on the single, multi-tenant sandbox service (this will also make it a lot easier if your tech needs to support side projects with shared functionality later)
  • All services should come with an SDK / client that works in the browser as well as node.js, with in-built knowledge of where the production and sandbox versions of the service live
  • Don’t allow two-way dependancies between services if at all possible:
    Service A depends on Services B + C — therefore Service B + C cannot ‘call’ Service A

--

--