Embedding a Microservice Into Another
Embedding a microservice into another is not a common practice, but it could open to new ways for developing service-oriented applications.
Join the DZone community and get the full member experience.Join For Free
Embedding a microservice into another means that a microservice can be run in the same execution context as a parent microservice. Such a mechanism is natively available in Jolie, a service-oriented programming language. Since it is not a native mechanism available in mainstream technologies, it is not widely used. But it allows dealing with microservices from a new and different perspective that opens up new ways for composing them. In this article, I will explain why.
What Is Embedding?
In the following diagram, the main concept behind embedding is reported.
On the left, two microservices are regularly deployed within different execution contexts and they are connected using the network. On the right, the same microservice composition is executed within the execution context of microservice 1 (the parent) and their connection is locally managed. It is worth noting that, in this case, both the microservices are fully defined together with their external interface. Thus they do not require to be manipulated in case they must be separated or aggregated, it is just sufficient to rebind their connection.
More services can be embedded into another, and a service that already embeds other services can be embedded again. Moreover, an embedded service can expose its operations outside, if properly configured to do that. In the following example, all the architecture is executed within the execution context of MS1, MS2 and MS3 have their own execution context with microservices MS4, MS5 and microservices MS6, and MS7 embedded respectively. Moreover, both MS1 and MS4 expose operations to be invoked from an external client.
Service Architecture Invariance
The first consequence of the embedding mechanism in a context of a service-oriented programming paradigm is that the service architecture is invariant with respect to the deployment. I already discussed such a concept in this article where I explained that decisions about the deployment can be postponed thanks to the fact that the deployment can be changed at any time. I think this is a useful consequence of embedding in a service-oriented programming paradigm because it provides a higher level of flexibility at the design time.
The dynamic embedding represents the possibility to embed a service at runtime. Such a feature may be used in two different ways:
- depending on the business logic of the embedder, some functionalities implemented in a different microservice can be run by picking up its definition from a repository. An example of such a scenario, written in Jolie, can be found here: a calculator service dynamically loads the operation to execute embedding the corresponding microservice (sum, sub, div or mul).
- an external client sends the service definition to be executed to the target microservice. The same example of the calculator, re-implemented exploiting the message passing, can be found here.
Dynamic embedding opens the way for a dynamic functional reconfiguration of a microservice, which could be useful in those scenarios where some functionalities must be dynamically updated at runtime or selected and executed depending on the context.
A New Perspective for Dealing With Microservice Composition
Embedding primitive allows for thinking about microservices in a different way with respect to what we use with traditional technologies because it permits us to treat a microservice as an integral unit of software. Such a fact has two main consequences:
- a microservice application is not necessarily deployed as a composition of distributed microservices, even if it is always designed as a distributed composition of microservices. A microservice indeed can be deployed as an independent service or it can be used as a library inside another microservice. Such an aspect allows to postpone the decision to deploy all the components as single independent services or as an agglomerate of embedded ones;
- dynamic embedding opens the possibility to design and implement dynamically reconfigurable microservices that are usually not considered at the design level
Embedding is a mechanism that allows for achieving some interesting aspects in microservice design and development like postponing deployment decisions and designing dynamically reconfigurable microservices. Moreover, thanks to embedding, developers can design and implement a service-oriented solution by never abandoning the service-oriented programming paradigm. The cognitive effort of the developer is finally reduced because he/she has only to deal with a unique programming paradigm instead of switching from a service-oriented model to another linguistic domain like an object-oriented one.
In Jolie, where embedding is natively supported, embedding and related aspects come for free, but if we consider traditional technologies it could be not so easy to figure out how embedding could work. Usually, in fact, a microservice is the engineering combination of a mix of technologies. If we consider the Java stack, for example, the public interface is defined using
openAPI, the service endpoints are managed with frameworks like springboot and, finally, the business logic is created using Java. This means that, in a traditional scenario, embedding a microservice should be achieved by embedding all the stack of technologies within the execution environment of a parent microservice, which is not so immediate. On the one hand, this fact allows for a better understanding of the contribution of a natively service-oriented programming language like Jolie is, on the other hand, it could trigger initiatives for adding the embedding mechanics also in traditional microservice technology stacks.
Opinions expressed by DZone contributors are their own.