Skip to main content

Ballerina — Why it is different from other programming languages?

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 thismedium 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 groupTwitterFacebookMedium or any other channel or by putting a comment to this post.

Comments

Popular posts from this blog

How to protect your APIs with self contained access token (JWT) using WSO2 API Manager and WSO2 Identity Server

In a typical enterprise information system, there is a high chance that people will use different types of systems built by different vendors to implement certain types of functionalities. The APIs might be hosted in an API Manager developed by vendor A and the user management can be implemented using a different vendor (vendor B). In this type of a situation, one system will not be able to directly contact the other system but they want to use both systems in tandem. Self-contained access tokens are used in these types of situations where applications can get the token from one system and use that in another system to access protected resources. In this scenario, the second system does not need to make a contact to the first system over the network to validate the user information since the token is self-contained and it has relevant details about the user. This will improve the token processing time significantly since it completely removes the network interaction. The below fig...

WSO2 ESB creating a response for a "GET" request

When you are creating REST APIs with WSO2 ESB, you may need to send some response message back to the user when something goes wrong. In this kind of scenario, you can create a payload inside the ESB and send it back. For doing this, you can use the below configuration. <api xmlns=" http://ws.apache.org/ ns/synapse " name="LoopBackProxy" context="/loopback">    <resource methods="POST GET">       <inSequence>          <property name="NO_ENTITY_BODY" scope="axis2" action="remove"></property>          <log level="full"></log>          <payloadFactory media-type="xml">             <format>                <m:messageBeforeLoopBack xmlns:m=" http://services...

WSO2 ESB usage of get-property function

What are Properties? WSO2 has a huge set of mediators but property mediator is mostly used mediator for writing any proxy service or API. Property mediator is used to store any value or xml fragment temporarily during life cycle of a thread for any service or API. We can compare “Property” mediator with “Variable” in any other traditional programming languages (Like: C, C++, Java, .Net etc). There are few properties those are used/maintained by ESB itself and on the other hand few properties can be defined by users (programmers). In other words, we can say that properties can be define in below 2 categories: ESB Defined Properties User Defined Properties. These properties can be stored/defined in different scopes, like: Transport Synapse or Default Axis2 Registry System Operation Generally, these properties are read by get-properties() function. This function can be invoked with below 2 variations. get-property(String propertyName) get-property(String scop...