blog posts

Ballerina for Full-Stack Developers: a Guide to Creating Backend APIs – InfoQ.com

Live Webinar and Q&A: Improving software quality with low-code development (Apr 14, 2022) Register Now
Facilitating the Spread of Knowledge and Innovation in Professional Software Development


This article explores Ballerina’s intuitive syntax for writing REST APIs. We also discuss authentication, authorization, OpenAPI tool, observability, SQL/NoSQL client libraries, and key language features. At the end of this article, you will have a good understanding of why Ballerina is a prominent candidate for writing your next backend API.
Each year, InfoQ editors discuss what we’ve been observing across the entire software development landscape, and create several trends reports, each with its own graph of the adoption curve. This helps the editorial team focus its reporting on innovative technologies and ideas, and also provides our readers with a high-level overview of topics to keep an eye on.
Zhamak Dehghani, Tareq Abedrabbo and Jacek Laskowski discuss the current challenges for building Modern Data Pipelines and applying Data Mesh in the real world, what the future looks like, and tools.
In the DACH region, a community of transformation leaders from about 30 companies started “DACH30” sessions where they share experiences and insights from their efforts to help their companies become more agile. This article highlights successful patterns to foster change, how to apply flow-oriented design to optimise your delivery capabilities, and the danger of the illusion of control.
Michael Barker surveys some of the alternative APIs available on various platforms, discussing some of the implementation pitfalls. He also looks at the impact of using these APIs.
Uncover emerging trends and practices from software leaders. Attend online on May 10-20, 2022.
Learn how cloud architectures achieve cost savings, improve reliability & deliver value. Register Now.
Understand the emerging software trends you should pay attention to. Attend in-person on Oct 24-28, 2022.
InfoQ Homepage Articles Ballerina for Full-Stack Developers: a Guide to Creating Backend APIs
This item in japanese
Mar 14, 2022 21 min read
by
Imesha Sudasingha
reviewed by
Daniel Bryant
A web app consists of 3 layers in the simplest form. Namely, the client side (frontend), server side (backend), and the persistence layer (database). Full-stack development refers to the practice of developing all 3 layers of a web application.

 
The platform to power synchronized digital experiences in realtime. Guaranteed to deliver at scale. Get started for free.
Out of all the technologies used under each layer mentioned above, there were some technologies more popular than the others. When such technologies that cover all 3 layers were combined, we called it “a stack.” We have seen several popular stacks over the years.
However, the stacks are not that simple anymore. For a given layer, available alternative technologies have multiplied. Within a given layer, the number of different technologies we can combine to develop the end product has also multiplied. 
When it comes to full-stack development, SPA (single-page applications) and PWA (progressive web applications) are becoming the norm and concepts like SSR (server-side rendering) have emerged to address limitations in them. These web applications (frontend) are supposed to work with a backend API (REST, GraphQL, etc.) to provide the ultimate functionality to the end users. With that, concepts like BFF (Backend for frontend) have emerged to align the backend APIs with the frontend user experience (UX).
An organization can have several microservices whose services are used by different parties like mobile applications, web applications, other services/APIs, and external parties. Modern web applications however need a tightly coupled API to work closely with the frontend UX. Therefore, a BFF acts as the interface between the frontend and the microservices.


 
With the above concepts in mind, let’s discuss a bit more about modern web development.
Developing backend APIs can mean 2 things:
In the context of full-stack development, we will only consider the backend APIs which are directly being invoked by a frontend. Those APIs can be written as BFF APIs or as separate microservices.
Nowadays, developers don’t just go for a stack just because it’s popular. They choose the best frontend technologies to match the UI/UX they wish to implement. Then they choose the backend technologies considering several factors including the time to market, maintainability, and developer experience. 
In this article, I’m going to introduce a new promising candidate for backend development, Ballerina. In the future, you can consider it while evaluating backend technologies for your full-stack journey.

 
Ballerina is an open-source cloud native programming language developed to make consuming, combining, and creating network services easier. Ballerina Swan Lake, the next major version of Ballerina language was released this year with major improvements to all aspects including an improved type system, enhanced SQL-like language-integrated queries, enhanced/intuitive service declarations, and many more.
The main motive behind ballerina is to enable developers to focus on business logic while spending less time on integrating cloud native technologies. The intuitive way of defining and running services on the cloud using Ballerina’s inbuilt network primitives plays a key role in this revolution. Flexible type system, data-oriented language-integrated queries, enhanced and intuitive concurrency handling along with inbuilt observability and tracing support, make Ballerina one of the go-to languages for the cloud era.
When developing APIs which are being invoked directly by the frontend, we have several popular choices:
Once a suitable API type is chosen, next we have to consider the following factors:
In addition to the above factors, we have to consider the maintainability and developer experience when developing the APIs. Let’s have a look at how Ballerina provides support for developing the above-mentioned API types and what makes Ballerina a promising candidate for backend API development.
One of the main objectives of the Ballerina programming language is to simplify writing network interactions. With that in mind, Ballerina has networking primitives inbuilt to the language. While all the other mainstream programming languages treat networking as just another I/O resource, Ballerina has first-class support for network interactions. To facilitate that, Ballerina has the following first-class components:
Listeners — Acts as the interface between the networking layer and the service layer. A listener represents the underlying transport like HTTP, gRPC, TCP, or WebSocket.
Services — Represents a service that exposes an organization’s capabilities to the end users. HTTP, GraphQL, gRPC, and WebSocket are a few examples of such services.
Resource Methods — Represents a unit of functionality within a service. For example, if we consider a simple CRUD service to manage inventory, add inventory is represented by a single resource method while delete inventory operation is represented by another.
Clients — Writing a service these days usually includes invoking one or more external or internal services. For example:
1. Within one of your services, you may want to send an email. For that, you need an email client.
2. The same service may have a requirement to invoke one or more internal gRPC services. For that, you need gRPC clients.
Similarly, writing services require invoking external services. For that, Ballerina has a rich concept called clients, and an external call is represented there by a remote method. Invoking a remote method in the Ballerina runtime is asynchronous (non-blocking, while no need for explicit callbacks or listeners).
These language inbuilt networking primitives coupled with other language features like explicit error handling, inbuilt json/xml support, and being flexibly typed help developers write intuitive and maintainable network interactions faster. This enables developers and organizations, in turn, to focus more on innovation.

 
Let’s explore how we can write intuitive and meaningful backend APIs with Ballerina using its support for REST and GraphQL APIs. Please follow the getting started guide to install and set up Ballerina.
Setting up Ballerina
Let’s have a look at how to write REST APIs with Ballerina.
A hello world REST API written in Ballerina looks like below:
Let’s decode each part of the syntax here:
The following diagram shows an overview of the Ballerina HTTP service syntax:

 
To get an in-depth understanding of the Ballerina HTTP service syntax, especially how to use query and path parameters, payload data binding, etc., please refer to the following article:
HTTP Deep-Dive with Ballerina: Services
The following is a bit more complex REST API. Given a baseCurrency, targetCurrency, and an amount, this API returns the converted amount. To get the latest exchange rates, this API uses an external service.
Compared to the hello world example, this one demonstrates a few more interesting features of Ballerina.
Once run, a curl request like below will convert 100 USD to GBP.
Ballerina has a leak-free graphical representation. That is, you can edit the source code and the low-code view (graphical representation) simultaneously. The following diagram is the low-code view of the above API:

Even though we will not be exploring the low-code aspect of Ballerina much, it is ideal for non-technical or less-technical people to understand and write code. Give it a try as well.
Leak Free — anything can be programmed in code and everything in code is visual.
The following is an example CRUD service written in Ballerina. It manipulates a set of products that are kept in memory.
While most of the syntax is self-explanatory, this service has 4 resource methods:
Note how the types have been defined to represent products, price, and currency. Then we have defined response types where necessary to achieve the desired schema. ProductCreated is to represent the response of adding a product. ValidationError is to represent an error in validation.
Having such a schema helps developers understand the code easily. Just by looking at the resource method definition, developers can get a clear overview of the resource method. What’s the resource path, what query/path parameters are required, what’s the payload, and what are the possible return types.
It’s a POST request, sent to the /products (derived by looking at the resource method’s), requires a payload of type Product and returns either a validation error (400) or an HTTP CREATED response (201) with a location header.
Once we have the service written in Ballerina, you can simply generate the OpenAPI specification just by pointing to the source file. It will output the OpenAPI specification with corresponding status codes and schema by looking at the source.
You can read more on that under the OpenAPI section:
Ballerina OpenAPI Tool
Generating a complete OpenAPI spec helps you to generate required clients. In our case, to generate JavaScript clients and integrate our frontend with the backend easily.
You can secure your service by updating the HTTP listener to an HTTPS listener as follows.
You can enable mutual SSL and do advanced configurations as well. Refer to the Ballerina examples on HTTP service security for more information.
Ballerina has inbuilt support for 3 authentication mechanisms.
You can either provide the cert file or the JWKs endpoint URL of your authorization server and enable JWT signature validation. For example, if we are to protect our service with an IDaaS (Identity as a Service) like Asgardeo, we just have to add the following annotation to the service:
Additionally,
Refer to the REST API Security section of Ballerina examples to learn more.
Similarly to JWT, you can protect your services with OAuth2. Refer the Service – OAuth2 example for more details.
For basic auth, 2 user store options are available; file and LDAP. Please refer to the following examples to see how it is done:
With OAuth2 and JWT you can validate scopes per service or per resource. In both cases, you can specify a custom scope key. The default is scope. 
In the case of JWT, you can use a custom claim containing user roles (role-based access control — RBAC) or permissions (fine-grained access control) to authorize individual operations.
As shown above, the /products service validates if the incoming JWT has the product:view permission to list products and the product:create permission to create a product. The scopeKey is set to permissions which is the name of the claim in the JWT to look at for validation. Additionally, it validates the issuer and the audience.

Obviously, you have to communicate with external services when writing a backend API. At least you will need a database client. Be it a DB client, HTTP client or gRPC client, Ballerina got you covered very well. Most importantly, client calls are non-blocking in Ballerina with developers not having to add any callbacks or listeners.
Check out how convenient the clients are in Ballerina:
Additionally, Ballerina has rich support for resiliency. See following examples to get an idea on them:
To keep this article short, I’m not going to go in-depth on writing GraphQL APIs. However, similarly to the REST APIs, Ballerina has the same level of support for GraphQL services. Please refer to the following links to read more on this:
Read more on GraphQL in the Reference by Example section of the Ballerina website for more information on writing GraphQL services.
I will not be discussing this in-depth as well. Please refer to the WebSockets and WebSocket security sections under the Reference by Example section of the Ballerina website for more details on writing WebSocket services.
Observability is one of the key features inbuilt to the language. With Ballerina, you can perform distributed tracing and metric monitoring out of the box.
Distributed tracing is available via Jaeger and Choreo. In order to publish traces to Jaeger (or Choreo), you just have to add an import to your code. During runtime, your services will then publish traces to Jaeger (or Choreo) using the Open Telemetry standards.

 
The logging framework provided by Ballerina is ideal for log analysis using logstash and similar log analyzers. While writing code, you can pass additional key value pairs to the log line.
The output of the above log line looks like:
Real-time metrics can be monitored with Prometheus and grafana. Additionally, you can monitor live metrics using Choreo.. 

 
Similarly to distributed tracing, you just have to add an import to your source code and import a ready-made grafana dashboard to publish and monitor real-time metrics.

 
Read more on Ballerina observability features from the following links:
The next major aspect in backend development is the persistence layer. Ballerina has a rich list of SQL and NoSQL DB clients.
DB calls made via clients are non-blocking in Ballerina
The following clients are available as of now:
Additionally, Ballerina comes with a very convenient way of writing prepared statements using RawTemplates.
In the above example, ${<variableName>} represents variables bound to the query and the above piece of code is executed as a prepared statement in the runtime.
Data Binding and Streams
Similarly, we can fetch data as a stream of a user-defined type using select queries as follows. Suppose we have a Product record as below:
And the product table is defined as below:
You can fetch data as a stream of Product records as below:
Note that the record field names and fetched column names are similar.
On top of the usual benefits of NoSQL, Ballerina’s inbuilt JSON and open record types come in handy when working with unstructured or semi-structured data.
Note: The Ballerina ecosystem is still growing. Therefore, a fully capable ORM library is not yet available.
As we have already seen, Ballerina has inbuilt support for popular wire formats, JSON, and XML. With Ballerina, you can seamlessly convert between user-defined types and JSON as we saw in HTTP services and DB examples.
Instead of nominal typing (as in Java/Kotlin), Ballerina relies on the shape of the construct (like in Go/TypeScript) to determine subtypes. This allows developers to seamlessly convert among user-defined types and among user-defined types and JSON.
Ballerina is statically typed. This enables Ballerina to provide a rich set of tools to write reliable and maintainable code. At the same time, Ballerina follows the “open by default” principle where you only have to define what you are interested in. Open records are one example of this usage.
Errors should be handled explicitly. As we saw in examples, client calls return a union of the result and an error. Developers should type check for errors and handle them explicitly.
Ballerina is null safe
With all the above aspects combined, Ballerina becomes a maintainable and reliable language tailored for network programming.
As we have seen briefly, Ballerina has a really good, leak-free low-code aspect. Ballerina uses sequence diagrams to visualize network interactions. This is really good for less technical and non-technical people to program and to understand a program.
In this article, I wanted to give a brief, but comprehensive overview of the Ballerina programming language’s support for writing backend APIs. We covered how we can write REST APIs in depth. And we looked at how to secure services, how to perform authentication and authorization, and generating OpenAPI specifications.
Next, we looked briefly at how we can write GraphQL and WebSocket services. Then we looked at the observability features and the persistence layer support (for SQL and NoSQL databases). Finally, we looked at a few of the Ballerina language features which are noteworthy.
I think the discussed content will be helpful for you to explore the Ballerina programming language more. And to understand its prominence in the context of backend API development. I hope I was able to establish the fact that Ballerina is a true cloud native programming language that treats network primitives as first-class citizens. I invite you to explore more on the Ballerina programming language.
Thank you for following this article. Feel free to share your opinions and suggestions. Also, reach out to me or the Ballerina community if you have further questions.

A round-up of last week’s content on InfoQ sent out every Tuesday. Join a community of over 250,000 senior developers. View an example

We protect your privacy.
You need to Register an InfoQ account or or login to post comments. But there’s so much more behind being registered.
Get the most out of the InfoQ experience.
Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

A round-up of last week’s content on InfoQ sent out every Tuesday. Join a community of over 250,000 senior developers. View an example

We protect your privacy.
Real-world technical talks. No product pitches.
Practical ideas to inspire you and your team.
QCon Plus – May 10-20, Online.
QCon San Francisco – Oct 24-28, In-person
QCon brings together the world’s most innovative senior software engineers across multiple domains to share their real-world implementation of emerging trends and practices. Find practical inspiration (not product pitches) from software leaders deep in the trenches creating software, scaling architectures and fine-tuning their technical leadership to help you make the right decisions.
InfoQ.com and all content copyright © 2006-2022 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we’ve ever worked with.
Privacy Notice, Terms And Conditions, Cookie Policy

source

Leave a Reply

Your email address will not be published.