MACH Alliance: decomposing monoliths -- building headless open cloud microservices
This is a guest post for the Computer Weekly Open Source Insider written by Kelly Goetsch in his capacity as president of the MACH Alliance – a group that has come together to promote open tech ecosystems that are Microservices-based, API-first, Cloud-native SaaS and Headless.
If you are a developer working for a company whose main business application is a monolith or ‘black box’, you can appreciate the issues and challenges of converting that suite into a set of intelligent, cloud-enabled applications.
A monolith has numerous, complex technical requirements, both in terms of hardware and system architecture. Every developer and administrator knows what this complexity means for software development, maintainability and operation of the application. Upgrades, patches or migrations cause extensive downtime and maintenance windows continually risk bringing the company to a halt.
Legacy applications also often rely on outdated technologies and architectures such as Cobol. A Java or PHP backend with frontend components that directly call the backend components (e.g. via JSPs) can cause problems. Here, code changes in the backend often mean that changes must be made in the frontend. Modular development is almost impossible and often means that source code is duplicated, or inheritance depths can’t be mapped.
The net result is that suite based legacy structures have become cumbersome and difficult to evolve.
MACH (M) – microservice
The M in MACH stands for microservice architectures. Microservices can be provided individually on separate servers with fewer resources – only what is required for each service and the host system itself.
Microservice-based architecture follows the principles of event-driven architecture and service-oriented architecture (SOA), where complex applications consist of small independent processes that communicate over a network using APIs.
MACH (A) – API
Hence the A in MACH. APIs allow access by other internal services of the same application or external services and third-party applications. Each microservice is developed and written in a modern programming language that is selected to best suit the type of service and its business function. This provides a high degree of flexibility in coordinating microservices with specific hardware, so that they can be used on low-cost, standard boxes.
Although the distributed nature of microservices makes the architecture more complex, one of the biggest advantages is scalability. As the overall application becomes modular, each microservice can be scaled individually, either manually or automatically through on-demand auto-scaling.
Seamless upgrades and patching processes are further advantages. There is virtually no downtime or service interruption for customers because upgrades are seamless – one service at a time, rather than recompiling, rebuilding and restarting an entire monolithic application. As a result, organisations can develop and deploy new features and updates much faster, in an agile approach with separate teams focusing on separate functions, making them more productive and cost effective.
Microservices models are an approach to developing an overall application as a group of small services, each running as a separate process and communicating with each other through simple mechanisms, often HTTP-based APIs.
It is advisable to adapt these services to the operational possibilities and to implement them independently from a fully automated implementation process. There is only a minimum of centralised management for these services and developers can work with services that are easier to understand and maintain.
In most monolithic applications, there is a clear separation between the external presentation (user interface) and the internal, corporate data access. Both are usually connected via an API interface. By dividing the application along this interface, you get two smaller, more manageable applications.
Companies should pay special attention to the internal security of a microservices application. It is worth paying attention to the security threats posed by other components of the application. Even if they can be trusted at first, nobody knows how the user group of the application will develop.
The first step should be a standardisation to TLS (Transport Layer Security). Certificate checks for both users (clients) and providers (servers) should be built into the architecture. The potential performance impact can be minimised by accelerating proxy servers.
Microservices offer a larger attack surface than monoliths. It is therefore important to be aware of the differences in security aspects and to react accordingly. Microservices communicate between different services. Microservices used to be on the same server but are now distributed across different servers and the cloud and communicate over a network. If someone enters the network, for example, by inserting a data probe, they can see a lot of traffic with potentially confidential information.
One way to protect organisations from this is to use SSL. In addition, the use of unique identifiers for each transaction, such as OpenTracing, is critical when recording and auditing operations.
MACH (C) – cloud
The C in MACH stands for Cloud – specifically cloud-native applications. There are numerous possible applications for microservice and API-based systems and providers of on-demand cloud based microservices and APIs. Microservices can be deployed in containers (e.g. Docker or Kubernetes) and operated in the cloud.
It is very easy to cluster and scale the containers. There are cloud-based platforms that are developed with an API-First approach and take the above as the basis of their architecture.
MACH (H) – headless
Finally, the H in MACH stands for Headless. In such an architecture, the CMS or shop system only takes over the task of providing content – such as articles, products, images, prices. Access is provided via, mostly JSON-based APIs, also known as Content APIs. As a result, the frontend is completely decoupled and renders content independently. For example, what used to be embedded Twig templates (PHP) are now standalone React applications.
Headless has both advantages and disadvantages. The whole system becomes a bit more complex because there are more components involved. So, we have Editor Facing Side (EFS), the backend and Client Facing Side (CFS), the actual frontend and of course the APIs themselves. More complexity results from the fact that functionalities such as form generators, which are already included in monolithic platforms, must be emulated in EFS/CFS.
The typical headless web application consists of the following components:
- Content/Catalog Repository – has the sole purpose of storing content and providing CRUD and search functionality.
- Authoring – a Web-based application that allows authors to create and modify content, create new types of content, collaborate and organise the publishing workflow.
- Delivery – uses REST APIs to make data available to an application that gives external entities access to content published and stored in the content or catalog repository.
The advantages of MACH can be thus best summarised in five categories:
- Clear boundaries: Each component has clear tasks. These can be developed by different people, teams, or even external companies.
- Future-proof: Interfaces to new devices and services change faster than the core functions themselves. This more precise separation means that it will also be possible to act faster and more cost-effectively.
- Security: APIs allow clear control of who is allowed to do what, where and when. In the event of a fault or an attack, for example, the CFS could be deactivated without disrupting the operation of the EFS.
- Scalability: If the CFS is located in a dynamic cloud service, for example, an additional instance can be brought online at the click of a mouse and more accesses can be processed.
- Extensibility: API extensions for new requirements, such as new apps, are often completed faster and easier in a few separate modules than in a monolithic codebase.