blog
Using GSL’s Mix-in Pattern to Reduce Complexity
Read more to the role of GSL mix-in objects when dealing with common configuration challenges.
March 16, 2023
When designing the Greymatter Specification Language (GSL) our foundational goal was to improve the developer experience. GSL’s most powerful aspect in this regard is its usage of the mixed-in pattern. In this blog we will highlight the role of GSL mix-in objects when dealing with some common configuration challenges and use cases.
Introducing CUE
CUE, which stands for “Configure, Unify, Execute”, is a modern-day configuration language born from the experiences ex-Googlers learned from managing highly scaled environments. CUE establishes a language centered around modeling data and data schemas as one cohesive concept–this is a novel approach to configuration management and one which has significant benefits for sprawling systems. Coupled with the core language features of CUE is its powerful tooling ecosystem, including Go APIs and a scripting layer, which enables developers to generate schemas and code, validate existing structures, and write custom tools on top of CUE.
Introducing Greymatter Specification Language (GSL)
GSL is a declarative domain specific language built on top of CUE. We designed it primarily to ease the burden associated with configuring application networking rules within a modern mesh-like topology. It innovates in this space by providing natural object relationships and drop-in customization. As a result, GSL empowers users from across the experience spectrum to make sophisticated application networking configuration changes rapidly and with confidence.
Dealing with Common Configuration Challenges
Boiler-plating and duplication problems are common configuration challenges that impact several IT teams at scale. Many configuration languages seek to solve these issues with templating or inheritance-based systems. However, these approaches tend to degenerate into unmaintainable messes. Composition is an alternative solution that doesn’t suffer from many of the pitfalls in inheritance-based systems. CUE believes composition is more effective than inheritance for solving configuration challenges, and we agree which is why GSL leans heavily into the “mix-in” compositional pattern.
The mix-in pattern refers to the process of supplementing a base type with extra, more powerful features (the history of the term comes from mixing toppings into ice cream). GSL accomplishes this by exporting a library of configuration blocks. Each one of these blocks has a base type it modifies. When embedded, the mix-in object expands the base type with extra behaviors.
Ultimately, mix-in objects reduce configuration repetition without sacrificing readability like many alternative tactics. These benefits translate to a friendlier experience for Greymatter users.
Examples
Let’s look at some examples.
Our first example involves enabling mTLS between two data plane proxies.
```
"destination-proxy": {
gsl.#Upstream
gsl.#MTLSUpstream
namespace: "destination-namespace"
}
```
In this case, the base type is the `#Upstream` definition and the mix-in type is the `MTLSUpstream` definition.
Amazingly, this is a valid and complete GSL upstream.
Our second example continues with the security theme.
Here, GSL also exports a mix-in object for SPIRE-based mTLS connections:
```
“destination-proxy”: {
gsl.#Upstream
gsl.#SpireUpstream & {
context: context.SpireContext
#subjects: [“destination-proxy”]
}
namespace: “destination-namespace”
}
```
The preceding example is a bit longer than manual mTLS, but that's because SPIRE requires more information. Yet, with only two simple fields, the basic upstream connection still becomes a secured and authenticated channel.
Let’s look at one final example.
Traffic shaping, or, controlling where traffic goes on a network is a common networking feature in modern application networking patterns. In this case, Blue-Green deployment is one use case. In our example, traffic shaping in GSL uses the #SplitTraffic mix-in object, like so:
```
upstreams: {
“destination-blue”: {
gsl.#Upstream
namespace: “destination-namespace”
traffic_options: gsl.#SplitTraffic & {
weight: 8
}
}
“destination-green”: {
gsl.#Upstream
namespace: “destination-namespace”
traffic_options: gsl.#SplitTraffic & {
weight: 2
}
}
}
```
Here we declare two upstreams, the blue and the green deployments. As a result, we shift 80% of the traffic to the blue one, and 20% to the green one. We could also continue to add more upstreams and subdivide the traffic weights even more if required.
Conclusion
In sum, the benefits of this mix-in pattern should be quite clear. By relying on declarative structures, there is no longer a need to memorize deeply-nested configuration blocks and replicate them numerous times across the entire project. GSL mix-ins take care of the painful parts of configuration, letting developers get back to what they enjoy above all: developing.
Interested in learning more about how Greymatter can help your team? We invite you to try our platform for 30 days! Contact us or schedule a demo to learn how Greymatter.io can help your enterprise control complexity, secure applications and see real-time operations.
Article Author: Jack Bischoff
Additional Reading: