In my second post about architecture design we will discuss IDEALS. If you’re unfamiliar with SOLID, please check it out here before diving into this blog post. After reading this article, you’ll be able to consider not only your software application but also the cloud infrastructure level.

⚡ TL;DR

  • IDEALS is often regarded as the microservices equivalent of the SOLID principles in object-oriented design

  • IDEALS stands for 6 principles: Interface segregation, Deployability, Event-driven, Availability over consistency, Loose coupling, Single responsibility

  • This article is specifically tailored for engineers who want to learn specially modern software architecture and design patterns

  • This article might interest you if you’re an Architect, Backend Developer, or SysAdmin looking to make the transition from legacy systems to modern software services

Until now, I’ve been part of teams that have already adopted a relatively modern tech stack, emphasizing software design based on cloud and microservice architecture. Consequently, I haven’t dedicated as much thought to what constitutes a well-designed microservices.

However, it’s valuable to understand when to opt for a monolithic approach versus a microservice architecture and what considerations should be taken into account. Let’s explore what defines a microservices, how it differs from service-oriented and monolithic architectures, and when each approach is most appropriate.

Monolith vs Service-Oriented vs Microservices

Software architectures

Monolith Service

A monolithic architecture is a classical software design approach where all components are tightly integrated into a single, self-contained unit, operating independently of other applications.

Pros & Cons

Developing, testing, and deploying a monolith is straightforward due to its single-unit nature, but it becomes increasingly challenging to scale and maintain as the application grows. Monolithic services tend to have faster performance because they don’t incur network overhead, making latency a non-issue.

Service Oriented Architecture

SOA is a more abstract architectural style that emphasizes breaking down an application into services with well-defined interfaces, similar to microservices. SOA and Microservices both implement distributed systems. SOA generally features larger and more comprehensive services, emphasizing interoperability and centralized governance.

Pros & Cons

This approach makes it easy to reuse services in different applications, but it requires extra work for managing and coordinating these services, which can cause delays due to network communication too.

Microservice Service

In contrast, Microservices are known for their fine-grained, small services that prioritize loose coupling and decentralized governance. They frequently use lightweight protocols like HTTP/REST for communication.

Pros & Cons

This approach provides agility, scalability, and simple maintenance. However, it introduces complexity in managing multiple services. Each service can employ its preferred technology stack to ensure fault tolerance, preventing a single service failure from impacting the entire system, as each component is scalable and replicated. It comes with operational overhead, demanding robust infrastructure and DevOps practices, which can result in increased latency due to network communication.

So, you’ve chosen to adopt a microservice architecture and you’re well-positioned to harness the power of this approach with your team’s expertise. As you embark on this journey, it’s essential to explore the five pillars of IDEALS, which are essential for building robust and resilient systems. Let’s dive in and discover how microservices can help you excel in terms of Interface segregation, Deployability, Event-driven, Availability over consistency, Loose coupling and Single responsibility.

Principle 1: Interface segregation

The goal of interface segregation in microservices is to ensure that each type of frontend perceives the service contract that best suits its needs. This results in more efficient and effective communication between different parts of a system or application, enhancing overall system flexibility, maintainability, and scalability.

Backend For Frontend

The first option is the Backend for Frontends (BFF) pattern, which is used to improve the efficiency and flexibility of frontend development by providing a backend service that delivers precisely the data and functionality required by the frontend, without overloading it with unnecessary or generic features.

API Gateway

Another popular choice is employing an API gateway pattern, which serves as a centralized, single point of entry into microservice applications. The API gateway plays a pivotal role in managing the complexities of client-microservice interactions. It acts as a gatekeeper, streamlining communication, enhancing security, optimizing performance, and simplifying the integration process, ultimately contributing to the overall efficiency and effectiveness of a microservices-based architecture.

Principle 2: Deployability

devops lifecycle

Microservice architecture significantly increases the need for (and frequency of) deploying applications. It leads to a larger number of modules, each running on multiple nodes dynamically managed by cloud platforms. Simultaneously, organizations place a high priority on automating their entire deployment process, spanning from development environments to production (CI/CD). The proficiency of development teams is now measured by their capacity to swiftly and effortlessly deploy top-notch products.

Principle 3: Event-driven

message driven

In the microservice architecture style, backend service communication is typically managed using three main types of connectors:

  • An HTTP call to a REST service.
  • An RPC-like call using platform-specific component technologies like gRPC or GraphQL.
  • An asynchronous message passing through a queue in a message broker (i.e. Kafka, PubSub)

The first two are usually synchronous, with HTTP calls being the most common. Services often need to interact with others., and this interaction is often synchronous. However, if we design or adapt the participating services to communicate and exchange messages via a queue or topic, we create an event-driven architecture. The terms “message-driven” and “event-driven” are often used interchangeably to describe asynchronous communication over a network using a message broker, such as Apache Kafka, RabbitMQ or another Cloud solution.

Principle 4: Availability over consistency

Availability over Consistency means that in a microservice system, it’s more important to keep the services up and running, even if they sometimes provide slightly outdated information, rather than making sure the information is always completely up to date but risking the services going down.

For example: Today’s e-commerce apps aim for faster page loading, even if it means showing not entirely accurate data. Research shows that users leave if the cart, products, or reviews take too long to appear. It’s okay to display a product, even if it’s out of stock. Users can add it to the cart, and a final check during checkout can confirm product availability. This helps keep customers engaged. Companies don’t want users to leave due to slow page loading. They need time to check stock and other carts for accurate product availability. In this situation, having the data available is more important than having it perfectly consistent.

In microservices, the primary strategy that supports the choice for availability is data replication. This foundational approach comes into play when a microservice requires access to data from external applications, and traditional API calls are not the most suitable means of retrieval. In this pattern, a duplicate copy of the required data is generated, ensuring its immediate availability to the microservice. Various design patterns (e.g. ETL, publisher-subscriber, Materialized Views) can be used, and sometimes in combination.

Principle 5: Loose coupling

Loosely coupled software components or modules are designed to interact with each other with minimal knowledge about each other’s inner workings. Imagine you’re building a modern e-commerce platform using a microservices architecture. For instance, the product catalog microservice doesn’t need to understand whether the request is coming from the mobile app or the web app. It simply provides product information when asked, and it doesn’t care who’s asking. To make the services loosely coupled, you can follow different decoupling methods (publisher-subscriber, API gateway, BFF, etc.)

Principle 6: Single responsibility

single response principle

The Single Responsibility Principle (SRP) is one of the five SOLID principles of object-oriented design, and it’s a fundamental concept in software engineering. In the context of microservices, adhering to SRP means that each microservice should have a single, well-defined responsibility. For example, an e-commerce site for order processing should focus solely on handling orders and related tasks. This division of responsibilities ensures that each microservice can evolve independently, making the entire system more robust, adaptable, and maintainable.

Conclusion

Occasionally, discussions may arise when you’re embarking on the design of a software architecture, comparing OOP to microservices or weighing the merits of “SOLID vs. IDEALS.” These principles can complement but each other when designing software. In this learning journey, we’ve built a solid foundation in microservice design and architecture, and we’re excited to dive deeper into these subjects in upcoming blog posts. When focusing on the application level, it’s beneficial to consider SOLID principles, while at the component or infrastructure level, IDEALS principles come into play. For those interested in delving deeper into IDEALS, visiting the original site of Paulo Merson, where he provides in-depth details on the concept, is recommended.

Stay tuned for the next installment, where we’ll dive into the exciting world of service mesh!