days
1
9
hours
0
4
minutes
5
0
seconds
3
3
search
It will come in handy

Ballerina programming language: The missing link in enterprise integration

Anjana Fernando
Ballerina
© Shutterstock / Sofia Zhuravetc

Do we really need yet another programming language? Well, in this case, the answer is yes. Ballerina, the cloud-native programming language has been architected to solve the problems we face now. Let’s go through some of these challenges and see how Ballerina tackles them.

It’s hard to imagine that we need another programming language. However, if you’ve ever tried to do a quick service or a client implementation from your favorite programming language, you probably spend considerable time figuring out the build dependencies, adding boilerplate code for a service template, and so on. If you want to add more functions, for example, adding resiliency for your services or container deployment, that creates another learning curve and more configuration complexity.

This is where you could use Ballerina, the cloud-native programming language architected to solve the problems we face now. Let’s go through some of these challenges and see how Ballerina tackles them.

Service interactions

Nowadays software doesn’t function alone; it works as a system of integrated components and services. This increases dependence on network-accessible APIs, bringing new challenges to the development environment. Traditional general-purpose programming languages provide only the bare bones for writing logic using code; any other extended functionality needs to be written from scratch or by using an external library with the functionality.

For example, making an HTTP service call to another service requires getting a client library dependency using an API. Then, to handle communication outage scenarios, such as retries or timeouts, you’ll probably plugin another library to provide the resiliency features. The Ballerina programming language itself does all this by being aware of the interactions with other services and reliably handling service calls.

SEE ALSO: The rise of Ballerina: An important piece of the microservices architecture puzzle

Ballerina has a native construct for an endpoint, where multiple types of endpoints, such as HTTP, WebSockets, and FTP are available. Listing 01 below shows how Ballerina code is used to define an HTTP endpoint and invoke an action on it. This level of functionality empowers developers to concentrate on the business logic of their software rather than the plumbing that makes it work. Developers can work more on the higher layers, and then drill down into the lower level technical details only when needed.

import ballerina/http;

endpoint http:Client clientEndpoint {
	url: "https://postman-echo.com",
circuitBreaker: {
	rollingWindow: {
    	timeWindowMillis: 10000,
    	bucketSizeMillis: 2000
	},
	failureThreshold: 0.2,
	resetTimeMillis: 10000,
	statusCodes: [400, 404, 500]
}
};

function main(string... args) {
	var response = clientEndpoint->get("/get?test=123");
}

Concurrency

Ballerina is designed from the ground up to consider the efficient and intuitive use of concurrency constructs in the language. It introduces a lightweight construct known as a worker, which represents the basic execution construct of Ballerina. Every Ballerina function is made up of one or more workers.

function f1(s) {
	worker w1 {
    	    io:println("Hello, World! #m");
	}
	worker w2 {
    	    io:println("Hello, World! #n");
	}
	worker w3 {
    	    io:println("Hello, World! #k");
	}
}

Listing 02 shows how for each function call, all the workers defined in the function will get executed concurrently. Ballerina contains its internal scheduler and makes sure the workers are executed in an optimal way using operating system-level threads. For example, with a network call, the calling worker goes into a special state, and the backing thread is immediately released.The system uses non-blocking I/O features to notify the worker and bring it back to life when responses are available. Developers do not have to worry about callbacks being registered and can just proceed in following a natural programming pattern as if they are doing a synchronous function call.

Ballerina also supports fork/join constructs to implement a pattern of splitting the execution for multiple parallel executions and then joining the responses of all into a single execution. Additionally, it has the ability to make any function or action call execute asynchronously, so developers can wait for or check on the call response later when needed.

Transactions

Transactions are critical in software systems for ensuring that actions and data are in a consistent state. Ballerina has language-level constructs for handling transactions, which let developers do local transactions with connectors, distributed transactions with X/A compatible connectors, or even service-level transactions with the built-in coordination support available in the language runtime.

Doing a set of actions transactionally is just a matter of wrapping all the operations in a “transaction” block as shown in Listing 03.

transaction {
  _ = testDB->update("INSERT INTO CUSTOMER(ID,NAME) VALUES (1, 'Anne')");
  _ = testDB->update("INSERT INTO SALARY (ID, MON_SALARY) VALUES (1, 2500)");
}

Secure coding

Ballerina has been designed with security in mind, and the programming language works to mitigate security vulnerabilities. One aspect of this is its taint checking functionality. This feature ensures that any untrusted data, such as data retrieved from user input or network communications, are marked as “tainted.” Therefore, any data derived from the source is also tainted, and afterwards, the compiler will conduct a static analysis of the code to check if this tainted data is used for any security-sensitive parameters. Using this method makes sure Ballerina programs are resilient against security vulnerabilities, such as SQL injection, path manipulation, file manipulation, and similar attacks.

function secureOp(@sensitive string param) {
   /* the parameter "param" is guaranteed to be not tainted */
   ...
}

function main(string... args) {
	secureOp(args[0]); // compiler error
	if (isClean(args[0])) {
    	    secureOp(untaint args[0]); // explicitly untaint the data
	}
      // function is signalling it returns untaint data
	secureOp(cleanit(args[0])); 
}

function cleanit(string param) returns @untained string {
	// sanitize the data and return it
	...
}

Listing 04 shows an example of taint checking in Ballerina. If the pattern is followed as a best practice in creating APIs, we can eliminate most of the developer bugs leading to security vulnerabilities.

Textual and graphical syntaxes

Ballerina language semantics make it natural for a developer to express the structure and logic of a program. Usually, to visualize complex interactions between multiple parties, we use a sequence diagram. This approach lets developers visualize endpoints and actions, such as asynchronous and synchronous message passing and parallel executions, in an intuitive manner. So in Ballerina, any code developers write has a corresponding graphical representation by means of a sequence diagram.

Figure 1

Figure 2

Figures 1 and 2 are examples of textual and graphical representations in Ballerina containing a client service call and a parallel worker processing scenario, respectively.

Summary

Ballerina is a general-purpose programming language, specializing in integration. And one could argue that the first-class integration capabilities are required in a modern programming language. Given the rapid growth of network-accessible APIs, having effective techniques is critical in consuming and creating compositions based on these resources. Ballerina contains native constructs for such concepts as services, concurrency, secure coding, and transactions, among others.

For a full guide on all of Ballerina’s features and rich set of ready-to-run examples, refer to https://ballerina.io/learn/.

asap

Author

Anjana Fernando

Anjana Fernando is a director and architect at WSO2. He is a key part of WSO2’s Ballerina and ecosystem engineering team where he spearheads efforts to shape the capabilities offered in the related technology areas.

He has also contributed to WSO2’s integration-related projects, including the Ballerina programming language, in the areas of the VM, transactions, and data handling. He has carried out several onsite customer engagements providing support for various integration and analytics projects as well.

Anjana has a first class honors degree in Software Engineering from the Informatics Institute of Technology, Sri Lanka, which is affiliated with the University of Westminster, UK. He also has a Masters in Computer Science from University of Colombo, School of Computing, where his main research area was distributed systems on the web.


Leave a Reply

Be the First to Comment!

avatar
400
  Subscribe  
Notify of