<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rosheni_Bolonne</title>
    <description>The latest articles on DEV Community by Rosheni_Bolonne (@roshenia11y).</description>
    <link>https://dev.to/roshenia11y</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3966821%2F1139066c-c42b-459d-bb00-f7eda9c0615c.png</url>
      <title>DEV Community: Rosheni_Bolonne</title>
      <link>https://dev.to/roshenia11y</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/roshenia11y"/>
    <language>en</language>
    <item>
      <title>I built an AI service in Ballerina - a language I'd never used. Here's what surprised me.</title>
      <dc:creator>Rosheni_Bolonne</dc:creator>
      <pubDate>Wed, 03 Jun 2026 15:54:42 +0000</pubDate>
      <link>https://dev.to/roshenia11y/i-built-an-ai-service-in-ballerina-a-language-id-never-used-heres-what-surprised-me-51jj</link>
      <guid>https://dev.to/roshenia11y/i-built-an-ai-service-in-ballerina-a-language-id-never-used-heres-what-surprised-me-51jj</guid>
      <description>&lt;p&gt;A few weeks ago I had a small task: build an API that takes a piece of text like a customer review, sends it to an AI model, and returns whether it's positive, negative, or neutral, with a one-line summary.&lt;/p&gt;

&lt;p&gt;If you'd asked me how I'd build it, I'd have said "Express, probably. Or Flask." That's my comfort zone. Instead I tried something I'd never touched: &lt;strong&gt;Ballerina&lt;/strong&gt;, an open-source language created by WSO2 for building APIs and connecting services.&lt;/p&gt;

&lt;p&gt;My first reaction to the syntax was honestly &lt;em&gt;"what is this?"&lt;/em&gt; It looks like Java and Python had a child. But by the end of the afternoon, I had a working service, and somewhere in the middle of building it, I understood &lt;em&gt;why&lt;/em&gt; this language exists. Here's the part that stuck with me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boring problem Ballerina is built for
&lt;/h2&gt;

&lt;p&gt;You only notice this after building a few backend services: most of your code isn't your actual logic. It's &lt;em&gt;plumbing&lt;/em&gt;. You receive a request, pull out the JSON, check it's the right shape, call some other service, handle it failing, reshape the response, and send it back. The interesting part "figure out the sentiment" is two lines. The rest is wiring.&lt;/p&gt;

&lt;p&gt;In most languages that wiring is bolted on with libraries. Ballerina's bet is to build the networking &lt;em&gt;into the language itself&lt;/em&gt;. Three things showed me what that actually means.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The endpoint &lt;em&gt;is&lt;/em&gt; the function
&lt;/h2&gt;

&lt;p&gt;In Express you write &lt;code&gt;app.post('/analyze', handler)&lt;/code&gt; - the route and the handler are two things you connect. In Ballerina they're one thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource function post analyze(AnalyzeRequest req) returns AnalysisResult|error {
    // ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The word &lt;code&gt;post&lt;/code&gt; is the HTTP verb. The name &lt;code&gt;analyze&lt;/code&gt; is the path. So this line &lt;em&gt;is&lt;/em&gt; &lt;code&gt;POST /analyze&lt;/code&gt;. No separate routing,the shape of my code is the shape of my API. And that &lt;code&gt;AnalyzeRequest req&lt;/code&gt;? Ballerina automatically pours the incoming JSON into a typed record, so by the time my code runs I already have a clean &lt;code&gt;req.text&lt;/code&gt;. No manual parsing.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.One little arrow that changes how you think
&lt;/h2&gt;

&lt;p&gt;To call the AI, I make this request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;groqClient-&amp;gt;post("/chat/completions", requestBody, headers);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at the arrow - &lt;code&gt;-&amp;gt;&lt;/code&gt;, not a dot. In Ballerina, &lt;code&gt;-&amp;gt;&lt;/code&gt; is reserved for &lt;strong&gt;network calls&lt;/strong&gt;. Local stuff uses a normal dot; anything that leaves your computer uses the arrow.&lt;/p&gt;

&lt;p&gt;At first I thought it was a quirk. Then it clicked: a network call is &lt;em&gt;fundamentally different&lt;/em&gt; from a local one ,it's slow, it can time out, the other side can be down. Ballerina makes that danger visible right in the syntax, so you can't forget you're crossing a boundary. Now plain dots everywhere feel like they're hiding something.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Errors you can't accidentally ignore
&lt;/h2&gt;

&lt;p&gt;My function returns &lt;code&gt;AnalysisResult|error&lt;/code&gt; - that bar means "either a result &lt;em&gt;or&lt;/em&gt; an error." Errors aren't thrown off to the side; they're a normal return value, sitting right there in the type.&lt;/p&gt;

&lt;p&gt;And the calls have a little &lt;code&gt;check&lt;/code&gt; in front:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GroqResponse groqResponse = check groqClient-&amp;gt;post(...);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;check&lt;/code&gt; means: &lt;em&gt;do this, but if it comes back as an error, stop here and pass that error up.&lt;/em&gt; It's the whole try/catch dance in five letters (if you know Rust's &lt;code&gt;?&lt;/code&gt; or Go's &lt;code&gt;err&lt;/code&gt;, it's that idea). My code reads top-to-bottom as the happy path, and &lt;code&gt;check&lt;/code&gt; quietly handles the failures without cluttering everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what's it actually for?
&lt;/h2&gt;

&lt;p&gt;Here's how I'd explain Ballerina to a friend now: &lt;strong&gt;it's for the glue.&lt;/strong&gt; The services whose whole job is to sit between other things calling APIs and databases, reshaping data, passing it along. Exactly the kind of work that keeps growing as we wire apps up to external APIs and, more and more, to AI models.&lt;/p&gt;

&lt;p&gt;My little feedback analyzer is a tiny version of a very real pattern: putting a clean, typed API in front of a language model so the messy outside world only ever sees something tidy. Ballerina made that feel natural instead of fiddly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest beginner take
&lt;/h2&gt;

&lt;p&gt;It wasn't all smooth,the syntax took a beat, and I leaned on the docs. There's lots I haven't touched yet: a real database instead of in-memory storage, tests, retries. But the thing that stayed with me is that I spent the afternoon thinking about &lt;em&gt;what I wanted to build&lt;/em&gt;, not &lt;em&gt;how to wire it up&lt;/em&gt;. For a language built for connecting things, that's the best compliment I can give it.&lt;/p&gt;

&lt;p&gt;If you usually build APIs the "import a framework and stitch it together" way, Ballerina is worth an afternoon of your curiosity.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The full project is on my GitHub:&lt;br&gt;
&lt;a href="https://github.com/Rosheni-a11y/ballerina-feedback-analyzer" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;br&gt;
if you'd like to poke around the code.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>ballerina</category>
    </item>
  </channel>
</rss>
