In this post, we’re going to talk about special features of the Ballerina language which are unique to itself. These features are specifically designed to address the requirements of the technology domain we are targeting with this new language.

XML , JSON and datatable are native data types

Communication is all about messages and data. XML and JSON are the most common and heavily used data types in any kind of integration eco system. In addition to those 2 types, interaction with databases (SQL, NoSQL) is the other most common use case. We have covered all 3 scenarios with native data types.

You can define xml and json data types inline and manipulate them easily with utility methods in jsons and messages packages.

json j = `{"company":{"name":"wso2", "country":"USA"}}`;
messages:setJsonPayload(m, j);

With the above 2 lines, you can define your own json message and replace the current message with your message. You can do the same thing for XML messages as well.

If you need to extract some data from a message which is of type application/json, you can easily do that with following lines of code.

json newJson = jsons:getJson(messages:getJsonPayload(m), "$.company");

The above code will set the following json message to the newJson variable.

{"name":"wso2","country":"USA"}

Another cool feature of this inline representation is the variable access within these template expressions. You can access any variable when you define your XML/JSON message like below.

string name = "WSO2";
xml x = `<name>{$name}</name>`;

The above 2 lines create an xml message with following data in it.

<name>WSO2</name>

You can do the same thing for JSON messages in a similar fashion.

Datatable is a representation of a pointer to a result set returned from a database query. It works in a streaming manner. The data will be consumed as it is used in the program. Here is a sample code for reading data within a ballerina program using the datatable type.

string s;
datatable dt = sql:ClientConnector.select(testDB, "SELECT int_type, long_type, float_type, double_type, boolean_type,
string_type from DataTable LIMIT 1",parameters);
while (datatables:next(dt)) {
s = datatables:getString(dt, "string_type");
// do something with s
}

You can find the complete set of functions in Ballerina API documentation.

Parallel processing is as easy as it can get

The term “parallel processing” scares even experienced programmers. But with Ballerina, you can do parallel processing as you do any other action. The main concept of term “Ballerina” stems from the concept of a ballet dance where so many different ballet dancers synchronized with each other during the dance act by sending messages between each other. The technical term for this process is called “Choreography”. Ballerina (language) brings this concept into a more programmer friendly concept with following 2 features.

Parallel processing with worker

The concept of a worker is that, it is an execution flow. The execution will be carried by the “Default Worker”. If the Ballerina programmer wants to delegate his work to another “Worker” which is working in parallel to the “Default Worker”, he can create a worker and send a message to that worker with the following syntax.

worker friend(message m) {
//Do some work here
reply m';
}
msg -> friend;
//Do my own work
replyMsg <- friend;

There are few things special about this task delegation.

  • worker (friend) will run in parallel to the default worker.
  • default worker can continue it’s worker independently
  • when default worker wants to get the result from the friend worker, it will call the friend worker and block their until it gets the result message or times out after 1 minute.

Parallel processing with fork-join (multiple workers)

Sometimes users needs to send the same message to multiple workers in the same time and process results in different ways. That is where fork-join comes into rescue. The Ballerina programmer can define workers and their actions within the fork-join statement and then decide on what to do once the workers are done with their work. Given below is a sample code of a fork-join.

fork(msg) {
worker chanaka(message m1) {
//Do some work here
reply m1';
}
worker sameera(message m2) {
//Do something else
reply m2';
}
worker isuru(message m3) {
//Do another thing
reply m3';
} join (all)(message[] results) {
//Do something with results message array
} timeout (60)(message[] resultsBeforeTimeout) {
//Do something after timeout
}

The above code sample is a powerful program which will be really hard to implement in any other programming language (some languages cannot do this even). But with Ballerina, you get all the power with simplicity. Here is an explanation of the above program.

  • workers “chanaka”, “sameera” and “isuru” are executed in parallel to the main “Default worker”
  • join condition specifies how user would need to get the results of the above started workers. In this sample, it waits for “all” workers. It is possible to join the workers in one of the following options

— join all of 3 workers

— join all of named workers

— join any 1 of all 3 workers

— join any 1 of named workers

  • timeout condition is coupled with the join block. User can specify the tiemout value in seconds to wait until the join condition is satisfied. If that join condition is not satisfied within the given time duration, timeout block will get executed with any results returned from the completed workers.
  • Once the fork-join statement is started and executing, “default worker” is waiting until it completes the join block or timeout block. It will be stayed idle during that time (some rest).

In addition to the above mentioned features, workers can invoke any function declared within the same package or any other package. One limitation with the current worker/fork-join implementation is that workers cannot be communicated with any other worker than “Default worker”.

Comprehensive set of developer tools to make your development experience as easy as it can get

Ballerina is not the language and the runtime itself. It comes with a complete set of developer tools which can help you to start your Ballerina experience as quickly and easily as possible.

Composer

The Composer is the main tool for writing Ballerina programs. Here’s some of what it can do:

  • Source, Design and Swagger view of the same implementation and ability to edit through any interface
  • Run/Debug Ballerina programs directly from the editor
  • Drag/Drop program elements and compose your program

Testerina

This is the unit testing framework for Ballerina programs. Users can write unit tests to test their Ballerina source code with this framework. It allows users to mock Ballerina components and emulate the actual Ballerina programs within a unit testing environment. You can find details from this medium post.

Connectors

These are the client connectors which are written to connect with different cloud APIs and systems. This is one of the extension points Ballerina has and users can write their own connectors from Ballerina language and use within any other Ballerina program.

Editor plugins

Another important set of tools coming with Ballerina tooling distribution is the set of editor plugins for popular source code editors like Intellij Idea, Atom, VSCode, Vim. This will make sure if you are a hardcore script editing person who is not interested in IDEs, you are also given the power of ballerina language capabilities in your favourite editor.

I am only half done with the cool new features of Ballerina, but this is enough for a single post. You can try out these cool features and let us know your experience and thoughts through our Google user group, Twitter, Facebook, Medium or any other channel or by putting a comment to this post.

--

--

Chanaka Fernando

Writes about Microservices, APIs, and Integration. Author of “Designing Microservices Platforms with NATS” and "Solution Architecture Patterns for Enterprise"