Wednesday, July 12, 2017

Design-first with Ballerina

Download this technical paper as a PDF.

The Need for Design-First

For almost as long as engineers have been integrating disparate/distributed systems together, there have existed the need for a common language, A common vocabulary that can dictate and specify the boundaries of the interfaces, allowing engineers to focus on the internal processing logic while mitigating interoperability concerns.

Though other technologies existed preceding it, an argument can be made that it was with the emergence of SOA and WSDL that an industry wide effort was first made to standardise the design of the interfaces that systems can expose for integration purposes. WSDL is an interface definition language which provides a means of specifying an interface’s operations, messaging format and data types in a manner that is implementation independent, this is achieved through the language agnostic quality of XML, the base language upon which WSDL was built.
Interface definition languages are tightly coupled with the technologies they are intended to be used with and built upon. With the fallout of XML seen in the last decade, and the rise of new architectural paradigms such as REST and ROA, a void was created in the IDL space. Swagger(Open API) was one such specification written to address this very need.

Apart from acting as a contract, definitions be it WSDL or Swagger provide an alternative way of approaching interface creation through the act of defining the contract prior to implementation. This approach referred to as “Design-first, “Contract-First” or “API-First”(a more vendor specific incarnation) allows organizations better segregation between the high level business requirements and lower functional/non-functional requirements.

Choosing Design-First for API

In their 2017 research on the consequences of API adoption on organizational performance, Benzell, Lagarda and Alstyne classifies API as either closed or open. Closed API are meant for internal consumption, whereas Open API are meant for external consumption, be it B2B or B2C. The researchers find a value increase of 10% and a profit increase of 5% for API adopters, the increase in valuation was driven mainly by Open API[1].

When designing Open API, those API that are expected to be consumed by outsiders, be it independent developers or strategic partners, it is important to provide a good developer experience for the consumer, as it plays an important role in forming opinions on the organization and the consequent success or failure of the API. As a means of addressing these concerns organizations may turn to “Design-First” and Swagger. Vasudevan identifies the following three situations as being ideal for this approach,

When Developer Experience Matters - a well designed API is easy to understand and use. As such they can be integrated into a developer’s applications faster, this leads to better adoption.

When Delivering Mission Critical APIs - In a B2B interaction, as the API acts as a channel of communication between the organization and its partners, the API consumption experience plays a role in forming opinions about the organization and such a thought out API design is a must.

When Ensuring Good Communication - At design and implementation time, having a central human readable contract allows for development teams to be in sync and identify design issue at a much earlier stage in the design lifecycle.    

According to Vasudevan though “Design-First” approach is best suited for the situations mentioned above code-first approach is likely to produce a better time-to-market. [3]

Moreover, “Design-first” provides the organization a means of addressing the developer experience through the separation of implementation from design. Similar to the the requirement specification endeavours of the monolithic software systems that required engineers specialized in requirement analysis and elicitation, the responsibility of the design can be handed over to those who specialize in the area before the design skeleton be handed over to those who specialize in implementation. The end result of this separation of concerns being the creation of a polished interface that is more in line with the business requirements and is of higher quality. [4]

In its short period of existence, Swagger(Open API Initiative) has amassed a healthy community reflected by its repository activity and usage in an estimated 10,000 production deployments. [2] In his comparison of Swagger with other API design tools Stowe finds it to have greater community support, language support and API building tools.[5] Using its many language support and API building tools/projects users may quickly proof their designs or generate implementation specific skeleton code.

Design First flow with Swagger

Design-first for Integration

Organizational information systems have moved away from being monolithic and disparate in favour of architectures that provide better agility such as Service Oriented Architectures and Microservices based Architectures. With the adoption of these architectures and the realization of the value creation of Open API, the number of API an organization needs to design and work with has seen an exponential increase. It is no longer enough to ensure the developer experience and quality of singular API, Organizations must work to increase these attributes in groups of API and API interactions. The parallelism posed by API interaction is a requirement that is beyond the capabilities of Swagger and is better addressed by another definition mechanism.             

In one post, Dr. Sanjiva Weerawarana, the founder of WSO2 speaks about how the integration space has become more parallel, he goes on to make an analogy of how the increased dependency on external network services in systems is similar to the way in which developers used to have to depend on external libraries to provide different capabilities to their programs.[6] It was with this intent of addressing the lack of proper definition mechanism for interaction/integration mechanism that the graphical syntax of Ballerina was birthed. Ballerina is a general purpose, concurrent and strongly typed programming language that is optimized for integration. Its graphical syntax is designed to resemble UML sequence diagrams, as such it can effortlessly capture the parallelism of integration scenarios as well as providing the missing element in an end-to-end “Design-First” adoption for organizations.

Ballerina Design-First Example  

With Ballerina, organizations can now define the contracts of singular API using Swagger and continue on to define the interaction between these API using the same tool. As Swagger is tightly integrated into the ballerina’s design tool, the composer, Swagger definitions seamlessly get translated into Ballerina code and diagrams.

Design-First flow with Swagger and Ballerina

Note: proceeding example is built around the service chaining sample shipped with the ballerina distribution. The ballerina code segments are compatible with the runtime version 0.89 and may not be compatible with other versions.

This example demonstrates how a simple service chaining scenario consisting three API may be constructed with a “Design-First” approach. ABC Bank API; is to act as the entry point for the user, it will orchestrate the interaction between the two other API, Branch Locator API; responsible for locating a branch based on a zip code provided and Bank Info API; responsible for providing information based on a branch code. Once the orchestration is complete, ABC Bank API responds back to the user.   

As the first step of constructing this scenario, the swagger definitions for the three API can be created. This step will allow the developer experience to be defined for each singular API, consultants may utilize the Swagger editor provided with the Ballerina Composer for this task or use any other editor they are familiar with. The resultant Swagger definitions will look similar to what’s found below,

At this time the ballerina composer requires the swagger definitions to be in JSON format in order for them to be imported. If the definitions were created using a third party editor they may be at once saved as JSON files. If this is not the case the definitions can be converted using free YAML to JSON converters available online.

The JSON conversions for the YAML definitions found above would be,

Next, the interaction between the three API should be designed. If the consultants used the Ballerina Composer for the previous step they may switch to design view and continue on to define the orchestration behavior using the Ballerina Graphical syntax. When designing this interaction consultants should utilize Function Constructs to abstract implementation level logic blocks in order to preserve design fidelity. The resultant diagram will look similar to,

In the above diagram the logic needed to prepare the payload for the Branch Info API and Bank Info API have been abstracted into functions prepareLocationServicePayload and prepareInfoServicePayload.

After this stage, the consultants may verify and proof the design before handing over the definitions to implementation specialists who may fill-in the design to construct the final ballerina deployable artifact(s). The resultant ballerina implementation for the ABC Bank API may take the shape of,

The implementation specialists may pack the services into a single deployable archive, such as the one found below,

Find out more about ballerina here: