There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.
— C.A.R. Hoare, Computer Scientist, Turing Award Recipient
When most people think of a mobile or web app, they usually focus on the user interface and the overall look and feel. However, there is usually an underlying backend supporting the product running behind the scenes. These can be called backends, API’s, services, etc…
When AD:60 takes on a project and starts the process of designing a backend, we try to break it down into smaller pieces. This allows us to focus on each piece individually and optimize it based on its responsibility to the application as a whole. In software development, we call this the single responsibility principle.
The problem most agencies face when doing this kind of development is that they don’t follow this principle all the way. After planning everything, we develop it into a single monolithic application becomes huge! Here are some of the hurdles we ran into using this strategy:
- Slower Releases
Code was starting to get super complex with thousands of little intricacies and cross-responsibility logic. These couplings were making releases difficult because every change we made had the risk of breaking another piece of functionality in the same code base. This was causing us to release new features slower and required way more upfront planning to ensure nothing broke.
- Complex Testing
With a complex code-base comes a complex test suite. When you have an array of conditions, mocks and assertions you end up maintaining two apps instead of one. Visibility also goes to zero as developers need to climb over unrelated tests to find what they are looking for. Reduced visibility creates a reduction in efficiency leading to bugs which are not caught due to poor test coverage.
- Scaling Risk
Having a single monolithic backend application creates a single point of failure and makes scaling difficult. Some of our clients are doing huge marketing pushes. Additionally, leveraging cloud services for scaling these types of applications depending on the complexity can only go so far.
Over the last year we have worked to adopt a new development/deployment strategy called Microservices to help solve these problems. This has really helped us accomplish the following:
- Faster Releases
We can now isolate development into separate services. This isolation reduces complexity and allows a us to focus on adding new features, for a specific service, faster and with less risk of breaking another portion of the app. This also provided an additional benefit with deployment where we can deploy a single service independent of others. We also adopted an automated process for our development and staging environments using CircleCi improving visibility into development for our Production and QA teams.
- Isolated Test Suites
Because of Microsevices, we can now break our test suite into smaller pieces instead of having one suite covering the entire application (think mini-apps). This type of testing (service by service) means that services only have to satisfy what they are responsible for. We can now isolate risk across functionality and develop in a simpler and more concise environment.
- Scale by Service
Using microservices we can scale a service independently of other services. We started treating each service as a separate Elastic Beanstalk environment. Environments can now have independent scalability based on needs of thier responsibility (ex. the User service running 8 instances while the content service is only using 3). Instances have also become smaller and more manageable and using tools such as CloudWatch have been a dream.
AD:60 has created an in-house framework to build microservices using NodeJS, this framework uses a number of design patterns that balance speed with reliability. We are very proud of our progress over the last year in this area and will continue to expand our strategy as we face new challenges. We are looking forward to the future and pushing this model even further with complementing strategies such as server-less architecture. Stay tuned!