You get a bonus - 1 coin for daily activity. Now you have 1 coin

Service-Oriented Architecture and the SAGA Pattern

Lecture



Service-oriented architecture (SOA) — a modular approach to software development based on the use of distributed, loosely coupled[en] replaceable components equipped with standardized interfaces for interacting over standardized protocols.

SOA and DDD are two concepts that work great together. DDD is a way to develop a unit of deployment (a single application). SOA is a way to glue together several units of deployment.

SOA:

an architectural style promoting the concept of business-oriented enterprise services as the fundamental unit of designing, building, and composing enterprise business solutions

DDD is:

a way of thinking and a set of priorities aimed at accelerating software projects that deal with complex domains
DDD is intended to build domain logic within the shared services of SOA

"A service is a visible resource that performs a repeatable task and is described by an external instruction."

The Open Group Architecture Forum (TOGAF) offers two definitions of architecture depending on the context:

  1. "A formal description or detailed plan of a system at the component level to guide its implementation.
  2. The structure of components, their relationships, and the principles and directions of development governing their design and evolution."

DDD vs SOA: what are the differences and what do they have in common?

Microservices are components, SOA is an architecture, so we cannot compare them. Microservices Architecture is primarily a concept at the application scale. Some of the recommendations may work at the enterprise level, but I think it depends on the scale and shape of the enterprise.

Service-oriented architecture is a concept that is more commonly used in enterprise architectures. This architecture is mainly used for better integration between numerous applications within an enterprise. Having said that, we can obviously apply some principles of microservices architecture within SOA to guide us in designing components in more modern ways. We just have to be aware that some of the principles of the two architectures are opposites, as I mentioned above.
Service-Oriented Architecture and the SAGA Pattern

Software systems developed in accordance with service-oriented architecture are usually implemented as a set of web services that interact over the SOAP protocol, but other implementations also exist (for example, based on Jini, CORBA, or REST).

Component interfaces in service-oriented architecture encapsulate implementation details (the operating system, platform, programming language) from the rest of the components, thereby enabling the combination and reuse of components to build complex distributed software systems, ensuring independence from the platforms and development tools used, and facilitating the scalability and manageability of the systems being built.

It became widespread in the late 1990s and early 2000s. Since the mid-2010s, microservices architecture has gained popularity — a variant of service-oriented architecture aimed at using modules that are as minimally coupled as possible.

The key ideas behind the concept of a service:

  • Business orientation: services are oriented not toward IT capabilities but toward business needs. The business orientation of services is supported by service analysis and design techniques.
  • Instructions: services are self-sufficient and are described in terms of interfaces, operations, semantics, dynamic characteristics, policies, and service properties.
  • Reuse: the reuse of services is ensured by their modular design.
  • Agreements: service agreements are made between entities called providers and consumers. These agreements are based on service instructions and do not affect the implementation of the services themselves.
  • Deployment and visibility: throughout their lifecycle, services are deployed and made visible through service metadata, registries, and repositories.
  • Aggregation: unifying business processes and complex applications for one or several enterprises are built on top of loosely coupled services.

Taken together, these characteristics show that SOA deals not only with "technologies" but also with the needs and requirements of the business.

Principles

There are no industry standards regarding the exact composition of service-oriented architecture, although many industry sources have published their own principles. Some of these include the following:

Standard service contract

Services adhere to a standard communication agreement, as defined collectively by one or more service description documents within a given set of services.

Service reference autonomy (an aspect of loose coupling)

The relationship between services is minimized to the level where they are aware only of each other's existence.

Service location transparency (an aspect of loose coupling)

Services can be called from anywhere in the network, wherever they are located.

Service longevity

Services must be long-lived. Wherever possible, services should avoid forcing consumers to change unless they require new functionality. If you call a service today, you should be able to call the same service tomorrow.

Service abstraction

Services act as black boxes, meaning their internal logic is hidden from consumers.

Service autonomy

Services are independent and control the functionality they encapsulate both during development and at runtime.

Service statelessness

Services are stateless, meaning they either return the requested value or throw an exception, which minimizes resource usage.

Service granularity

The principle of ensuring an adequate size and scope of services. The functionality provided by a service to a consumer must be relevant.

Service normalization

Services are decomposed or consolidated (normalized) to minimize redundancy. In some cases this is not possible. These are the cases where performance optimization, access, and aggregation are required. [15]

Service composability

Services can be used to create other services.

Service discoverability

Services are supplemented with communicative metadata by which they can be effectively discovered and interpreted.

Service reusability

Logic is divided into distinct services to promote code reuse.

Service encapsulation

Many services that were not originally planned within SOA can be encapsulated or become part of SOA.

Implementation technologies

The architecture is not tied to any particular technology. It can be implemented using a wide range of technologies, including technologies such as REST, RPC, DCOM, CORBA, or web services. SOA can be implemented using one of these protocols and, for example, may additionally use a file system mechanism to exchange data.

The main thing that distinguishes SOA is the use of independent services with clearly defined interfaces, which can be called in some standard way to perform their tasks, provided that the services know nothing in advance about the application that will call them, and the application does not know how the services perform their task.

Service-Oriented Architecture and the SAGA Pattern

Elements of service-oriented architecture, from: Dirk Krafzig, Karl Banke, and Dirk Slama. Enterprise SOA. Prentice Hall, 2005

SOA can also be viewed as an architectural style for information systems that makes it possible to build applications composed of loosely coupled, interacting services. These services interact based on some strictly defined platform-independent and language-independent interface (for example, WSDL). The interface definition hides the language-dependent implementation of the service.

Thus, systems based on SOA can be independent of development technologies and platforms (such as Java, .NET, etc.). For example, services written in C# running on the .Net platform and services written in Java running on the Java EE platform can be called with equal success by a common composite application. Applications running on some platforms can call services running on other platforms, which facilitates component reuse.

SOA can support the integration and consolidation of operations within complex systems; however, SOA does not define or provide methodologies or frameworks for documenting services.

High-level languages such as BPEL, or specifications such as WS-CDL and WS-Coordination, extend the concept of a service by providing an orchestration method for combining fine-grained services into larger business services, which in turn can be incorporated into technological processes and business processes implemented as composite applications or portals.

The use of Service Component Architecture (SCA) to implement SOA is an area of ongoing research.

Service-Oriented Architecture and the SAGA Pattern

Figure 1. Reference model of SOA foundation

Criticism

SOA has been conflated with web services; [30] however, web services are only one option for implementing the patterns that make up the SOA style. In the absence of native or binary forms of remote procedure call (RPC), applications may run slower and require more computing power, which increases costs. Most implementations incur this overhead, but SOA can be implemented using technologies (for example, Java Business Integration (JBI), Windows Communication Foundation (WCF), and Data Distribution Service (DDS)) that do not depend on remote procedure calls or translation via XML or JSON. At the same time, emerging open-source XML parsing technologies (such as VTD-XML) and various XML-compatible binary formats promise to significantly improve SOA performance. [31] [32] [33]

Stateful services require that both the consumer and the provider share the same consumer-specific context, which is either included in or referenced by the messages exchanged between the provider and the consumer. This constraint has the drawback that it can reduce the overall scalability of the service provider if the provider needs to retain a shared context for each consumer. It also increases the coupling between the service provider and the consumer and makes it harder to switch between service providers. [34] Ultimately, some critics believe that SOA services are still too constrained by the applications they represent. [35]

The main problem faced by service-oriented architecture is metadata management. SOA-based environments include many services that interact with each other to perform tasks. Because a design can involve multiple services working together, an application can generate millions of messages. Additional services may belong to different organizations or even competing firms, which creates an enormous problem of trust. Thus, SOA governance comes into the picture. [36]

Another serious problem faced by SOA is the lack of a unified testing environment. There are no tools that provide the functionality needed to test these services in a service-oriented architecture. The main reasons for the difficulties are: [37]

  • The heterogeneity and complexity of the solution.
  • A huge set of testing combinations due to the integration of autonomous services.
  • The inclusion of services from different and competing providers.
  • The platform constantly changes as new features and services appear.

Implementation approaches, extensions, and variants

Service-oriented architecture can be implemented using web services or microservices. [21] This is done so that functional building blocks are accessible over standard Internet protocols that are independent of platforms and programming languages. These services can represent either new applications or simply wrappers around existing legacy systems to make them available for use over the network. [22]

Developers typically build SOA using web service standards. One example is the SOAP protocol, which gained wide industry acceptance after the version 1.2 recommendation from the W3C consortium [23] (World Wide Web Consortium) in 2003. These standards (also called web service specifications) also provide greater interoperability and some protection against lock-in to proprietary vendor software. However, one can also implement SOA using any other service technology, such as Jini, CORBA, REST, or gRPC.

Architectures can operate independently of specific technologies and therefore can be implemented using a wide range of technologies, including:

  • Web services based on WSDL and SOAP
  • Messaging, for example, with ActiveMQ, JMS, RabbitMQ
  • RESTful HTTP with Representational State Transfer (REST) constituting its own constraint-based architectural style.
  • OPC-UA
  • WCF (Microsoft's web services implementation, which is part of WCF)
  • Apache Thrift
  • gRPC
  • SORCER

Service-oriented architecture (SOA) was conceived in the late 1980s. It originates in the ideas set out in CORBA, DCOM, DCE, and other documents. Much has been written about SOA, and there are several of its implementations. But in essence, SOA can be boiled down to a few ideas, and the architecture does not dictate how they are implemented:

  • The composability of user-oriented applications.
  • The reuse of business services.
  • Independence from the technology stack.
  • Autonomy (independent evolution, scalability, and deployability).

SOA is a set of architectural principles independent of technologies and products, just like polymorphism or encapsulation.

Let's consider the following patterns related to SOA:

  • Common Object Request Broker Architecture (CORBA).
  • Web services.
  • Message queue.
  • Enterprise Service Bus (ESB).
  • Microservices.

Common Object Request Broker Architecture (CORBA)

In the 1980s, the active use of corporate networks and client-server architecture began. A need arose for a standard way for applications to interact when they were built using different technologies, ran on different computers, and under different operating systems. CORBA was developed for this purpose. It is one of the standards for distributed computing, which emerged in the 1980s and flourished by 1991.

The CORBA standard was implemented by several vendors. It provides:

  • Platform-independent Remote Procedure Calls.
  • Transactions (including remote ones!).
  • Security.
  • Events.
  • Independence from the choice of programming language.
  • Independence from the choice of operating system.
  • Independence from the choice of hardware.
  • Independence from the specifics of data transfer/communication.
  • A data set via the Interface Definition Language (IDL).

Today CORBA is still used for heterogeneous computing. For example, it is still part of Java EE, although starting with Java 9 it will be shipped as a separate module.

I want to note that I do not consider CORBA a pattern of SOA (although I place both CORBA and SOA patterns in the field of distributed computing). I discuss it here because I consider the shortcomings of CORBA to be one of the reasons SOA emerged.

How it works

First, we need to obtain an Object Request Broker (ORB) that conforms to the CORBA specification. It is provided by a vendor and uses language mappers to generate «stubs» and «skeletons» in the languages of the client code. Using this ORB and the interface definitions that use IDL (an analog of WSDL), you can generate remotely callable stub classes in the client based on real classes. And on the server, you can generate skeleton classes that handle incoming requests and call the real target objects.

Service-Oriented Architecture and the SAGA Pattern

The caller invokes a local procedure implemented by the stub.

  1. The stub validates the call, creates a request message, and passes it to the ORB.
  2. The client ORB sends the message over the network to the server and blocks the current thread of execution.
  3. The server ORB receives the request message and creates an instance of the skeleton.
  4. The skeleton executes the procedure on the callee object.
  5. The callee object performs the computation and returns the result.
  6. The skeleton packs the output arguments into a response message and passes it to the ORB.
  7. The ORB sends the message over the network to the client.
  8. The client ORB receives the message, unpacks it, and passes the information to the stub.
  9. The stub passes the output arguments to the calling method, unblocks the thread of execution, and the caller continues its work.

Advantages

  • Independence from the chosen technologies (except for the ORB implementation).
  • Independence from the specifics of data transfer/communication.

Disadvantages

  • Location independence: the client code has no idea whether the call is local or remote. This sounds good, but the duration of the latency and the types of failures can vary greatly. If we do not know what kind of call we have, then the application cannot choose an appropriate strategy for handling method calls, and therefore may generate remote calls inside a loop. As a result, the whole system runs slower.
  • A complex, bloated, and ambiguous specification: it was assembled from several versions of specifications from different vendors, so (at the time) it was bloated, ambiguous, and difficult to implement.
  • Blocked communication pipes: specific protocols on top of TCP/IP are used, as well as specific ports (or even random ports). But corporate security rules and firewalls often allow HTTP connections only through port 80, blocking CORBA data exchanges.

Web services

Although today a use can still be found for CORBA, we know that it was necessary to reduce the number of remote calls in order to improve system performance. A reliable communication channel and a simpler messaging specification were also required.

And to solve these problems, web services began to appear in the late 1990s.

  • A reliable communication channel was needed, so:
    • HTTP started working over port 80 by default.
    • A platform-independent language (such as XML or JSON) began to be used for messaging.
  • It was necessary to reduce the number of remote calls, so:
    • Remote connections became explicit, so now we always know when a remote call is being made.
    • Instead of numerous remote calls to objects, we call remote services, but much less frequently.
  • It was necessary to simplify the messaging specification, so:
    • The first draft of SOAP appeared in 1998, became a W3C recommendation in 2003, and then turned into a standard. SOAP absorbed some ideas from CORBA, such as a layer for handling message exchange and a «document» that defines the interface using the Web Services Description Language (WSDL).
    • In 2000, Roy Fielding described REST in his dissertation «Architectural Styles and the Design of Network-based Software Architectures». His specification turned out to be much simpler than SOAP, so REST soon overtook SOAP in popularity.
    • Facebook developed GraphQL in 2012 and released it publicly in 2015. It is a query language for APIs that allows the client to strictly define what data the server should send it, no more and no less.

[Web] services can be published, discovered, and used in a standard way regardless of technologies.
— Microsoft 2004, Understanding Service-Oriented Architecture

Service-Oriented Architecture and the SAGA Pattern

Thanks to microservices, within the SOA paradigm we moved from remote method calls on objects (CORBA) to message passing between services.

But it is important to understand that within SOA, web services are not simply general-purpose APIs that merely provide CRUD access to a database over HTTP. In some cases this implementation can be useful, but for the integrity of your data it is necessary that users understand the model underlying the implementation and follow the business rules. SOA implies that web services are bounded contexts of business sub-domains and separates the implementation from the tasks solved by the web services.

From a technology standpoint, SOA is not just a service architecture, but a set of policies, practices, and frameworks through which we provide and obtain the services we need.
— Microsoft 2004, Understanding Service-Oriented Architecture

Advantages

  • Independence of the technology stack, deployment, and scalability of services.
  • A standard, simple, and reliable communication channel (transmitting text over HTTP via port 80).
  • Optimized message exchange.
  • A stable messaging specification.
  • Isolation of domain contexts.

Disadvantages

  • Different web services are hard to integrate because of differences in message languages. For example, two web services that use different JSON representations of the same concept.
  • Synchronous messaging can overload systems.

Message queue

We have several applications that communicate asynchronously with each other using platform-independent messages. A message queue improves scalability and strengthens the isolation of applications. They do not need to know where the other applications are, how many there are, or even what they are. However, all these applications must use a single messaging language, i.e., a predefined text format for representing data.

A message queue uses a software message broker (RabbitMQ, Beanstalkd, Kafka, etc.) as an infrastructure component. To implement communication between applications, the queue can be configured in various ways:

  • Request/Response

    • The client sends a message to the queue, including a reference to a «conversation». The message arrives at a special node that responds to the sender with another message containing a reference to the same conversation, so the recipient knows which conversation the message refers to and can continue to act. This is very useful for medium- and long-running business processes (chains of events, sagas).
  • Publish/Subscribe
    • By lists
      The queue maintains lists of published subscription topics and their subscribers. When the queue receives a message for some topic, it places it in the corresponding list. The message is matched to a topic by message type or by a predefined set of criteria, including the content of the message.
    • Based on broadcasting
      When the queue receives a message, it broadcasts it to all nodes listening to the queue. The nodes must filter the data themselves and process only the messages of interest.

Service-Oriented Architecture and the SAGA Pattern

All these patterns can be classified as either a pull (polling) approach or a push approach:

  • In a pull scenario, the client polls the queue at a certain frequency. The client manages its own load, but a delay may occur: the message is already in the queue, but the client is not yet processing it because the time for the next poll of the queue has not come.
  • In a push scenario, the queue immediately delivers messages to clients as they arrive. There is no delay, but the clients do not manage their own load.

Advantages

  • Independence of the technology stack, deployment, and scalability of services.
  • A standard, simple, and reliable communication channel (transmitting text over HTTP via port 80).
  • Optimized message exchange.
  • A stable messaging specification.
  • Isolation of domain contexts.
  • Ease of connecting and disconnecting services.
  • Asynchronous messaging helps manage the load on the system.

Disadvantages

  • Different web services are hard to integrate because of differences in message languages. For example, two web services that use different JSON representations of the same concept.

Enterprise Service Bus (ESB)

The Enterprise Service Bus was already using web services back in the 1990s, when they were just developing (perhaps some implementations initially used CORBA?).

The ESB arose at a time when companies had separate applications. For example, one for handling finances, another for personnel accounting, a third for warehouse management, and so on, and they needed to be linked and integrated with each other somehow. But all these applications were created without integration in mind, and there was no standard language for applications to interact (as there still isn't today). Therefore, application developers provided endpoints for sending and receiving data in a certain format. Client companies then integrated the applications, establishing communication channels between them and converting messages from one application's language into another.

A message queue can simplify the interaction of applications, but it is not able to solve the problem of different language formats. Nonetheless, an attempt was made to turn the message queue from a simple communication channel into an intermediary that delivers messages and converts them into the required formats/languages. The ESB became the next step in the natural evolution of a simple message queue.

Service-Oriented Architecture and the SAGA Pattern

This architecture uses a composite application, usually user-oriented, that communicates with web services to perform some operations. In turn, these web services can also communicate with other web services, subsequently returning some data to the application. But neither the application nor the backend services know anything about each other, including their location and communication protocols. They know only which service they want to communicate with and where the service bus is located.

The client (a service or a composite application) sends a request to the service bus, which converts the message into a format supported at the destination and forwards the request there. All interaction goes through the service bus, so if it goes down, all the other systems go down with it. That is, the ESB is a key intermediary, a very complex component of the system.

This is a very simplified description of the ESB architecture. Moreover, although the ESB is the main component of the architecture, other components may also be used in the system, such as Domain Brokers, Data Services, Process Orchestration Services, and Rules Engines. The same pattern can be used by a federated design: the system is divided into business domains with their own ESBs, and all the ESBs are connected to each other. Such a scheme has higher performance and no single point of failure: if some ESB goes down, only its business domain suffers.

Service-Oriented Architecture and the SAGA Pattern

The main responsibilities of the ESB:

  • Monitor and route the exchange of messages between services.
  • Transform messages between the communicating service components.
  • Manage the deployment and versioning of services.
  • Manage the use of redundant services.
  • Provide standard services for event processing, data transformation and mapping, message and event queue services, security or exception handling services, protocol conversion services, and services for ensuring the required quality of communication.

As we have built structures for communication between different processes, we have seen many products and approaches that use very sophisticated communication mechanisms. A good example is enterprise service buses, which often include sophisticated facilities for message routing, choreography, transformation, and applying business rules.
— Martin Fowler 2014, Microservices

This architectural pattern has its positive sides. However, I consider it especially useful in cases where we do not «own» the web services and need an intermediary to translate messages between services, to orchestrate business processes that use several web services, and for other tasks.

I also recommend keeping in mind that ESB implementations are already quite advanced and in most cases allow the use of a user interface with drag & drop support for their configuration.

Advantages

  • Independence of the technology stack, deployment, and scalability of services.
  • A standard, simple, and reliable communication channel (transmitting text over HTTP via port 80).
  • Optimized message exchange.
  • A stable messaging specification.
  • Isolation of domain contexts.
  • Ease of connecting and disconnecting services.
  • Asynchronous messaging helps manage the load on the system.
  • A single point for managing versioning and transformation.

Disadvantages

  • Lower communication speed, especially between services that are already compatible.
  • Centralized logic:
    • A single point of failure capable of bringing down the communication systems of the entire company.
    • Great complexity of configuration and maintenance.
    • Over time, you may end up storing business rules in the ESB.
    • The bus is so complex that you will need an entire team to manage it.
    • High dependence of services on the ESB.

Microservices

Microservices architecture is based on the concepts of SOA. Its purpose is the same as that of the ESB: to create a single shared enterprise application from several specialized business-domain applications.

The main difference between microservices and the bus is that the ESB was created in the context of integrating separate applications to produce a single enterprise distributed application. Whereas microservices architecture was created in the context of rapidly and constantly changing businesses that (mostly) build their own cloud applications from scratch.

That is, in the case of the ESB, we already had applications that we did not «own», and therefore we could not change them. But in the case of microservices, we fully control the applications (while third-party web services may also be used in the system).

The nature of building/designing microservices does not require deep integration. Microservices must correspond to a business concept, a bounded context. They must maintain their own state, be independent of other microservices, and therefore they need less integration. That is, low interdependence and high cohesion led to a remarkable side effect — a reduced need for integration.

[Microservices are] small autonomous services that work together and are designed around a business domain.
— Sam Newman 2015, Principles Of Microservices

The main disadvantage of the ESB architecture was a very complex centralized application on which all the other applications depended. But in microservices architecture, this application is almost entirely removed.

Some elements that permeate the entire microservices ecosystem still remain. But they have far fewer tasks compared to the ESB. For example, a message queue is still used for asynchronous communication between microservices, but it is merely a channel for passing messages, nothing more. Or one can recall the microservices ecosystem gateway, through which all external data exchange passes.

Sam Newman, the author of Building Microservices, identifies eight principles of microservices architecture. They are:

  • Designing services around business domains
    This can give us stable interfaces, highly cohesive modules of code that depend little on one another, and clearly defined bounded contexts.
  • A culture of automation
    This will give us much more freedom, and we will be able to deploy more modules.
  • Hiding implementation details
    This allows services to evolve independently of one another.
  • Full decentralization
    Decentralize decision-making and architectural concepts, give teams autonomy, so that the company itself turns into a complex adaptive system capable of quickly adapting to change.
  • Independent deployment
    You can deploy a new version of a service without changing anything else.
  • Consumer first
    A service must be easy to use, including by other services.
  • Isolating failures
    If one service fails, the others continue to work, which makes the entire system resilient to failures.
  • Ease of monitoring
    There are many components in the system, so it is difficult to keep track of everything happening in it. We need sophisticated monitoring tools that allow us to look into every corner of the system and trace any chain of events.

Service-Oriented Architecture and the SAGA Pattern

The community prefers a different approach: smart endpoints and dumb pipes. The microservices from which applications are assembled should depend on each other as little as possible while being very tightly cohesive — they contain their own domain logic and act more like filters in the classic Unix sense: they receive requests, apply logic, and generate responses. They are orchestrated using simple REST-like protocols rather than complex protocols such as WS-Choreography or BPEL or some centralized tool.
— Martin Fowler 2014, Microservices

Advantages

  • Independence of the technology stack, deployment, and scalability of services.
  • A standard, simple, and reliable communication channel (transmitting text over HTTP via port 80).
  • Optimized message exchange.
  • A stable messaging specification.
  • Isolation of domain contexts.
  • Ease of connecting and disconnecting services.
  • Asynchronous messaging helps manage the load on the system.
  • Synchronous messaging helps manage the performance of the system.
  • Fully independent and autonomous services.
  • Business logic is stored only in the services.
  • They allow the company to turn into a complex adaptive system consisting of several small autonomous parts/teams, capable of quickly adapting to change.

Disadvantages

  • High operational complexity:
    • You need to invest a lot in a strong DevOps culture.
    • The use of numerous technologies and libraries can get out of control.
    • You need to carefully manage changes to the input/output APIs, because these interfaces will be used by many applications.
    • The use of «eventual consistency» can lead to serious consequences that must be taken into account when developing the application, from the backend to the UX.
    • Testing becomes more complicated, because changes in an interface can unpredictably affect other services.

microservices architecture is a special case of SOA:

Service-Oriented Architecture and the SAGA Pattern

In other words, microservices architecture is just a set of stricter rules and conventions for writing all those same SOA services

  • SOA is oriented toward the reuse of application services, whereas microservices are more oriented toward decoupling.
  • SOA is monolithic in nature, whereas microservices are full-stack.
  • SOA applications are built to perform many business tasks, but microservices are built to perform a single business task.
  • SOA assumes the sharing of a data store between services, whereas in microservices each service can have an independent data store.
  • SOA is intended for sharing resources between services, whereas microservices are intended to host services that can operate independently.
  • In SOA architecture, DevOps and continuous delivery are becoming popular but have not yet become mainstream, whereas microservices place a great emphasis on DevOps and continuous delivery.
  • SOA is a less scalable architecture, whereas microservices are a highly scalable architecture.

Here are the differences between SOA and microservices:

SOA Microservices
The SOA model has a single data storage layer that is used by all services in the application. Microservices applications mostly allocate a database or other storage to the services that need it.
Communication between the various services in a SOA application uses simple and straightforward approaches. Microservices use complex APIs.
Focused on maximizing the reuse of application services. We pay more attention to decoupling.
A systematic change requires modifying the monolith. A systematic change will help you create a new service.
DevOps and continuous delivery are becoming popular but have not yet become mainstream. Strong emphasis on DevOps and continuous delivery
Monolithic in nature Full stack in nature
Supports multiple messaging protocols. Uses lightweight protocols such as HTTP, REST, or Thrift API.
It is intended for sharing resources between services. It is intended to host services that can operate independently.
Often involves sharing components As a rule, it does not involve sharing components
Assumes the sharing of a data store between services Each service can have an independent data store.
Better for large-scale integration Better for small and web applications.
Exchanges data through an ESB Communicate through an API layer
Relies on resource sharing Relies on a bounded context for communication.
Less flexibility in deployment Fast and simple deployment.
The SOA technology stack is lower compared to Microservice. The microservices technology stack can be very large.
Business units are dependent. Business units are independent of one another.
A SOA application consisting of two or three services. A Microservices application can have dozens of services.
SOA applications are built to perform many business tasks. They are built to perform a single business task.
Deployment is a time-consuming process. Deployment is uncomplicated and requires less time.
Business logic components are stored inside simple wire protocols (HTTP with XML JSON) in a single-service domain. The API is managed using SDKs / client packages. Business logic can exist across all domains of the enterprise service bus, as separate layers between services.
Uses an enterprise service bus (ESB) for communication It uses a less complex and simple messaging system.
The size of the software is larger than that of any ordinary software The size of the software in microservices is small.
Multithreaded with a lot of overhead for handling I/O Single-threaded, mainly used with Event Loop functions for non-blocking I/O handling.
A systematic change is required to modify the monolith. In microservices, a systematic change consists of creating a new service.
Focus on maximizing the reusability of application services. Emphasis on decoupling.
Unified governance and standards. Relaxed governance, since it is more oriented toward the collaboration of people and freedom of choice.
The deployment process takes a lot of time. Deployment is done easily and requires less time.
A less scalable architecture.

A highly scalable architecture.

Antipattern: Ravioli Architecture

Service-Oriented Architecture and the SAGA Pattern

Ravioli architecture is the name usually given to an antipattern of microservices architecture. You get ravioli if there are too many microservices, they are too small, and they do not reflect domain concepts.

Conclusion

In recent decades, SOA has evolved considerably. Thanks to the inefficiency of earlier solutions and the development of technologies, today we have arrived at microservices architecture.

The evolution followed the classic path: complex problems were broken down into smaller ones that are easy to solve.

The problem of code complexity can be solved in the same way that we break a monolithic application into separate domain components (bounded contexts). But as teams and the codebase grow, the need for independent development, scaling, and deployment increases. SOA helps achieve such independence by strengthening the boundaries of contexts.

Service-Oriented Architecture and the SAGA Pattern

I repeat that it all comes down to loose interdependence and high cohesion, and the size of the components should be larger than before. It is necessary to pragmatically assess your needs: use SOA only when it is necessary, since it greatly increases complexity. And if you can actually do without SOA, then it is better to choose microservices of an appropriate size and number, no more and no less.

Pattern: SAGA

Why are long transactions discouraged in SOA, with the use of a Saga proposed instead?

Context

You have applied the «Database per Service» pattern. Each service has its own database. However, some business transactions span several services, so you need a mechanism for implementing transactions that span services. For example, imagine you are building an e-commerce store in which customers have a credit limit. The application must ensure that a new order does not exceed the customer's credit limit. Since orders and customers reside in different databases belonging to different services, the application cannot simply use a local ACID transaction.

Problem

How to implement transactions that span services?

  • 2PC is not an option

Solution

The implementation of each business transaction that spans several services is a saga. A saga is a sequence of local transactions. Each local transaction updates the database and publishes a message or event to trigger the next local transaction in the saga. If a local transaction fails due to a violation of a business rule, then the saga executes a series of compensating transactions that undo the changes made by the preceding local transactions.

Service-Oriented Architecture and the SAGA Pattern

There are two ways to coordinate sagas:

  • Choreography — each local transaction publishes domain events that trigger local transactions in other services.
  • Orchestration — an orchestrator (an object) tells the participants which local transactions to execute.

Example: A choreography-based Saga.

Service-Oriented Architecture and the SAGA Pattern

An e-commerce application using this approach could create an order using a choreography-based saga that consists of the following steps:

  1. The Order Service receives the POST /orders request and creates an Order in the PENDING state
  2. It then emits an Order Created event
  3. The Customer Service event handler attempts to reserve credit
  4. It then emits an event indicating the result.
  5. The OrderService event handler either approves or rejects the Order

Example: An orchestration-based Saga.

Service-Oriented Architecture and the SAGA Pattern

An e-commerce application using this approach could create an order using an orchestration-based saga that consists of the following steps:

  1. The Order Service receives the POST /orders request and creates a Create Order saga Orchestrator
  2. The saga orchestrator creates an Order in the PENDING state
  3. It then sends a Reserve Credit command to the Customer Service
  4. The Customer Service attempts to reserve credit
  5. It then sends a reply message indicating the result.
  6. The saga orchestrator either approves or rejects the Order

Resulting context

This pattern has the following advantages:

  • It allows the application to maintain data consistency across multiple services without using distributed transactions.

This solution has the following disadvantages:

  • The programming model is more complex. For example, a developer must design compensating transactions that explicitly undo changes made earlier in the saga.

The following problems also need to be solved:

  • To be reliable, a service must atomically update its database and publish a message/event. It cannot use the traditional distributed transaction mechanism that spans the database and the message broker. Instead, it must use one of the patterns listed below.

  • A client that initiates a saga, which is an asynchronous flow, using a synchronous request (for example, HTTP POST /orders), must be able to determine its outcome. There are several options, each of which has its own trade-offs:

    • The service sends a response after the saga completes, for example, after receiving an OrderApproved or OrderRejected event.
    • The service sends a response (for example, containing an orderID) after starting the saga, and the client periodically polls (for example GET /orders/{orderID}) to determine the outcome
    • The service sends a response (for example, containing an orderID) after starting the saga, and then sends an event (for example, a web socket, webhook, etc.) to the client after the saga completes.

Related patterns

  • The Database per Service pattern creates the need for this pattern
  • The following patterns are ways to atomically update state and publish messages/events:
    • Event Sourcing
    • Transactional Outbox
  • A choreography-based saga can publish events using aggregates and domain events.

See also

  • software architecture
  • REST
  • SOASP
  • [[b6939]]
  • [[b7880]]
  • Event-driven architecture (EDA)
  • Staged event-driven architecture (SEDA)
  • Application programming interface
  • Loose coupling
  • OASIS SOA reference model
  • Service granularity principle
  • SOA governance
  • Software architecture
  • Service-oriented communication (SOC)
  • Service-oriented application development
  • Service-oriented distributed applications
  • DDD
  • [[b9117]]

See also

Comments

To leave a comment

If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Lectures and tutorial on "Software and information systems development"

Terms: Software and information systems development