When it comes to microservice-oriented architectures (MOA), good fences make good neighbors. One of the biggest problems in microservice-oriented architecture in general, and multi-cloud implementations in particular, is poorly defined context boundaries. A context boundary defines the features and data structures that represent a service or application to the outside world. In a Kubernetes environment, a context boundary can be expressed as a Kubernetes service. In object-oriented programming, a context boundary is expressed as public methods and data of a class. Regardless of the implementation, the concept driving context boundaries in MOA design is that activities within the context are private and opaque. And, activities and data structures that are publicly apparent are well-known. Being well-known means being discoverable and understandable.
Encapsulation works! DRY works!
For the most part, architects creating MOA applications tend to do a good job setting clear boundaries around behavior. For example, an application will almost never allow outside actors direct access to data storage or authentication mechanisms. This type of behavior has become a conventional no-no. However, supporting clear context boundaries around data structures is another matter. There are applications out there that will use different names for attributes that are semantically identical; for example, using both the terms
zip_code to refer to that unique geographic location identifier. (See Figure 1, below)
This might seem like no big deal, but it is. It degrades the context boundary. And, when it comes time to support change, using two names to refer to one thing violates the principle of Do Not Repeat Yourself (DRY).
Typically, controlling context boundary in an MOA is hard enough, but when you move to one that is multi-cloud, operating over many domains, things can become unyielding. When you have domains in play, something as obvious as semantic naming collision among data structures can go unnoticed.
Use a schema registry as a sole source of truth
So then, what's a good way to create clear context boundaries around data structures? One way is to use a schema registry as the sole authority for your data structures. There are a few out there, including Red Hat Service Registry, Confluent's Kafka Schema Registry, and dedicated registries for each cloud provider.
Granted, things can get tricky when committing yourself to a particular cloud provider's schema registry when working in a multi-provider architecture. You will have to declare one provider the authority. But having the benefit of a single source for defining data structures and being able to create solid context boundaries based on those structures outweighs the risk of dedicating yourself to a single provider. And, should you need to make a change and move to another provider, it's a controllable event.
Good error messages reinforce context boundaries
Another way to maintain clear context boundaries is error handling at the programming level. The odds are more than likely that some developer somewhere will try to violate the context boundary by using the application the wrong way. Providing descriptive error messages that report the error, the cause of the error, as well as a possible solution will go a long way toward protecting your application's context. It will also provide a way for developers to use the application in the manner you want it used. Or, to put it another way, good fences with clear warning signs are less inviting to trespassing than those without. (See Figure 3.)
Putting it all together
Establishing well-known, well-understood context boundaries is essential to reducing the burden of managing complexity in microservice-oriented architectures.
History has shown that software systems usually become more complex over time. As systems grow, there is a tendency for entropy to set in. As a result, context boundaries that used to be well-defined at the initial release of the application can become muddied when the MOA gets years into service. Yet, when MOA architects have the foresight to build in the mechanisms necessary to maintain clear context boundaries between the many microservices that make up the MOA, the rate of entropy will decrease, thus making change more manageable.