Application Patterns in SolSA
Many cloud-native applications are built incrementally over time. Developers start with simple, common architectural patterns that they progressively refine into sophisticated, custom solutions. Using SolSA, a developer can encode architectural patterns into executable code. These patterns can then be instantiated, customized, or composed to create more complex solutions.
Previously, we showed how to deploy one containerized microservice using SolSA. Today, we will first describe how a developer can leverage SolSA to define an application composed from multiple microservices. Then we will refine this application using a managed service from IBM’s public cloud. Concretely, we will show how to use SolSA to combine the Istio project’s Bookinfo sample application and IBM’s Watson Language Translator service into an enhanced application that provides automatically translated book reviews to its users.
Bookinfo in SolSA
Istio’s Bookinfo sample application consists of four containerized microservices: a front-end productpage
service that aggregates information from three additional back-end services to present users with a web site containing book descriptions. We use SolSA’s ContainerizedService abstraction to specify each of these services. By adding entries to the bundle.productpage.env
dictionary, we specify environment variable bindings for the productpage
microservice that enable it to connect to its back-end services. Finally, to make productpage
accessible outside of the Kubernetes cluster, we specify that it should have an Ingress.
As described in a previous SolSA blog, to generate the YAML needed to actually deploy this application to a Kubernetes cluster we use the command sosla yaml bookinfo.js
. From the above 14 lines of JavaScript, sosla yaml
will generate around 180 lines of YAML that declare 9 Kubernetes resources (4 Services, 4 Deployments, and 1 Ingress). When we apply the generated YAML to a Kubernetes cluster and point a browser at the deployed application we will see the basic Istio Bookinfo as shown below
Building an Enhanced Bookinfo
When using SolSA, all the features of the JavaScript language are available for the developer to use. In particular, we can make it easier to reuse the configuration of the four Bookinfo microservices in a larger application by encapsulating the SolSA code that configures them in a function.
The base Bookinfo application can then be instantiated by invoking the bookinfo
function. More interestingly, we can take the Bundle object returned by invoking bookinfo
, add additional resources to it, and even modify its existing resources. The snippet below enhances our application by injecting a new reviews translation service between the existing productpage
and reviews
microservices.
Line 6 invokes bookinfo
to get a Bundle defining Bookinfo we can extend. Lines 8–18 add the translating review service to the Bundle, using two features of SolSA that will be explored in more depth in subsequent blog posts. Line 9 creates an instance of a LanguageTranslator, a managed service on the IBM Public Cloud that will be managed by an instance of the IBM Public Cloud Operator. The ContainerizedService instance declared in line 10 uses the build
and main
arguments to instruct SolSA how to containerize the Express.js application that does the work of translating book reviews. It does this by routing the book review text obtained from the original reviews
microservice through the Watson Language Translator before returning it to productpage
. Connections between the various pieces are captured by environment variable bindings: lines 12–16 configure reviews-translator
and line 21 updates an entry in the productpage
environment to replace the original reviews
microservice with the new reviews-translator
.
We can now use solsa yaml
to generate the 260 lines of YAML that declare the 13 Kubernetes resources that are needed to deploy the enhanced application. When we point a browser at the deployed application we will see Bookinfo with reviews translated to another language, in this case Spanish:
In this example, we simply patched the productpage
environment to change its review service. With slightly more work, we could have made the review service name a parameter of the bookinfo
function and bound the parameter to reviews-translator
, avoiding the mutation altogether.
Summary
Minimally extending the SolSA encoding of Bookinfo to transform it from a stand-alone application to an application fragment that can be embedded into other applications did not require much work. This example illustrates one of the strengths of the SolSA approach. By using a full-fledged (scripting) language, to define software architectures, developers can gain access to a whole toolbox of programming language mechanisms for building abstractions and optionally encapsulating implementation details. An application’s architecture becomes just another program to create, maintain, and evolve using the same familiar set of languages, tools and methodologies that the developer already knows.
Many cloud-native applications contain recurring architectural patterns and frequently used-together components. Using SolSA, a developer can create a toolbox of reusable architectural patterns. These patterns can then be instantiated, customized, or composed to create more complex solutions.
Links
- Complete SolSA code for Bookinfo: https://github.com/IBM/solsa-examples/tree/master/examples/bookinfo
- NPM package: https://www.npmjs.com/package/solsa
- Main SolSA repository: https://github.com/IBM/solsa
- SolSA examples and tutorial: https://github.com/IBM/solsa-examples