<?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>Forem: Shailendra Kumar Gupta</title>
    <description>The latest articles on Forem by Shailendra Kumar Gupta (@shailendra53).</description>
    <link>https://forem.com/shailendra53</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%2F3151056%2F3d01bcfb-1acf-452e-8508-812cdde22a7c.png</url>
      <title>Forem: Shailendra Kumar Gupta</title>
      <link>https://forem.com/shailendra53</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/shailendra53"/>
    <language>en</language>
    <item>
      <title>Mastering Multi-Cloud with Go: A Practical Guide to the Cloud Development Kit</title>
      <dc:creator>Shailendra Kumar Gupta</dc:creator>
      <pubDate>Mon, 26 May 2025 19:21:10 +0000</pubDate>
      <link>https://forem.com/shailendra53/mastering-multi-cloud-with-go-a-practical-guide-to-the-cloud-development-kit-516g</link>
      <guid>https://forem.com/shailendra53/mastering-multi-cloud-with-go-a-practical-guide-to-the-cloud-development-kit-516g</guid>
      <description>&lt;p&gt;Have you ever worked on applications that interact with multiple cloud providers to store or retrieve data?&lt;/p&gt;

&lt;p&gt;Yes?&lt;/p&gt;

&lt;p&gt;Then you know the pain of writing custom code for each cloud provider’s API. With so many providers on the market, it’s crucial to support as many as possible to attract and retain customers. This flexibility allows customers to choose the best cloud for their needs — otherwise, it’s easy to lose them.&lt;/p&gt;

&lt;p&gt;However, each cloud provider has its own API for interacting with cloud storage, making multi-cloud support in a single application challenging. Every new cloud adds more code to maintain.&lt;/p&gt;

&lt;p&gt;What if there were a &lt;strong&gt;common interface&lt;/strong&gt; that allowed developers to write generic code to interact with any cloud storage?&lt;/p&gt;

&lt;p&gt;This is where the &lt;strong&gt;Go Cloud Development Kit (Go CDK)&lt;/strong&gt; comes in — a set of Go libraries providing a common interface to interact consistently with multiple cloud providers. The goal is to help developers write cloud-agnostic code that runs in any environment with minimal changes.&lt;/p&gt;

&lt;p&gt;In this article, I’ll show how to use Go CDK to write cloud-agnostic code for interacting with cloud storage &lt;strong&gt;and&lt;/strong&gt; the local file system. Yes, it even supports the local file system, making it a very flexible solution for all types of storage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Overview: The &lt;code&gt;blob&lt;/code&gt; Package
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;blob&lt;/code&gt; package is a core component of Go CDK, used to &lt;strong&gt;read&lt;/strong&gt;, &lt;strong&gt;write&lt;/strong&gt;, &lt;strong&gt;list&lt;/strong&gt;, and &lt;strong&gt;delete&lt;/strong&gt; blobs (objects/files) from underlying storage.&lt;/p&gt;

&lt;p&gt;It uses drivers to support multiple cloud providers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;fileblob&lt;/strong&gt;: Local filesystem storage
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gcsblob&lt;/strong&gt;: Google Cloud Storage
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;s3blob&lt;/strong&gt;: Amazon S3
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;azureblob&lt;/strong&gt;: Azure Blob Storage
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;memblob&lt;/strong&gt;: In-memory storage (useful for testing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you understand the basics, let’s dive into some code examples demonstrating how to use Go CDK in Go applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation and Setup
&lt;/h2&gt;

&lt;p&gt;Install Go CDK using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get gocloud.dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This article uses Google Cloud Storage (GCS) for demonstration.&lt;/p&gt;

&lt;p&gt;For GCS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download your service account JSON and set it as an environment variable:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GOOGLE_APPLICATION_CREDENTIALS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;PATH_TO_JSON_FILE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(You can download this from your GCS service account settings.)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a bucket in GCS where you will write objects/files.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Writing an Object to a GCS Bucket
&lt;/h2&gt;

&lt;p&gt;The following example reads data from a local input file and writes it as an object to a cloud bucket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;testStoringFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bucketURL&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usage: go run main.go -bucket BUCKET_URL -file FILE_PATH -object OBJECT_NAME"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenBucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bucketURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to open bucket %q: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bucketURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to open file %q: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to create writer for object %q: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// ignore error from Close if copy fails&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to write data to object %q: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to close writer for object %q: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Successfully uploaded %q to bucket %q as object %q&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bucketURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bucketURL&lt;/code&gt;: The bucket where the object will be stored
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;filePath&lt;/code&gt;: The local file to read
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;objectName&lt;/code&gt;: The name of the object to write in the bucket&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Reading an Object from a GCS Bucket
&lt;/h2&gt;

&lt;p&gt;This example opens an object in a bucket and prints its contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;testReadingFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenBucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bucketURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to open bucket: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to open blob reader: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to read blob data: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Contents of %s:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Listing All Objects in a Bucket
&lt;/h2&gt;

&lt;p&gt;This function lists all objects in the specified bucket along with their sizes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;testListingFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenBucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bucketURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to open bucket: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;iter&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListOptions&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EOF&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to list objects: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Deleting an Object from a Bucket
&lt;/h2&gt;

&lt;p&gt;The following code deletes a specified object from the bucket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;testDeletingFile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenBucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bucketURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to open bucket: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bucket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to delete object %q: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Successfully deleted object %q from bucket %q&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;objectName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bucketURL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Supported Storage Providers and Bucket URLs
&lt;/h2&gt;

&lt;p&gt;The above functions work with any of the following storage providers by using the appropriate bucket URL scheme:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Bucket URL Scheme&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Google Cloud Storage&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gs://{bucket-name}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon S3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;s3://{bucket-name}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure Blob Storage&lt;/td&gt;
&lt;td&gt;&lt;code&gt;azblob://{container-name}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local File System&lt;/td&gt;
&lt;td&gt;&lt;code&gt;file:///{file-path}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope this article has given you a clear understanding of how to use Go CDK in Go applications. Try out these examples to get hands-on experience. In the future, consider using Go CDK to build cloud-agnostic applications — it simplifies multi-cloud deployment by abstracting provider-specific differences behind a single interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important note:&lt;/strong&gt; Go CDK supports accessing objects in cloud storage (read, write, list, delete), but it &lt;strong&gt;does not&lt;/strong&gt; support creating buckets. To create buckets, you’ll need to use cloud-specific libraries. For example, to create a bucket in GCS, you must use the Google Cloud Storage client library: &lt;code&gt;cloud.google.com/go/storage&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus Tool Recommendation
&lt;/h2&gt;

&lt;p&gt;If you’re tired of spending time searching for and understanding internal APIs, check out the AI tool &lt;strong&gt;&lt;a href="https://hexmos.com/landing/liveapi/" rel="noopener noreferrer"&gt;LiveAPI&lt;/a&gt;&lt;/strong&gt;. It helps you discover, understand, and use APIs within large codebases, making your API work much easier.&lt;/p&gt;

</description>
      <category>cdk</category>
      <category>api</category>
      <category>gcs</category>
      <category>go</category>
    </item>
    <item>
      <title>The API Boom: How AI Is Supercharging the Future of Software</title>
      <dc:creator>Shailendra Kumar Gupta</dc:creator>
      <pubDate>Sun, 18 May 2025 13:35:45 +0000</pubDate>
      <link>https://forem.com/shailendra53/the-api-boom-how-ai-is-supercharging-the-future-of-software-478h</link>
      <guid>https://forem.com/shailendra53/the-api-boom-how-ai-is-supercharging-the-future-of-software-478h</guid>
      <description>&lt;p&gt;Hey everyone,&lt;br&gt;
I'm Shailendra.&lt;br&gt;
Recently, I was studying more about APIs while diving deeper into APIs and exploring how the space is evolving, I stumbled upon a few really interesting reports—especially the &lt;a href="https://treblle.com/news/anatomy-of-an-api-report-2024" rel="noopener noreferrer"&gt;Treblle API Report for 2024&lt;/a&gt;. That got me digging further, and I came across even more articles and stats showing just how fast the API market is growing.&lt;/p&gt;

&lt;p&gt;Here are a few links worth checking out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://treblle.com/news/anatomy-of-an-api-report-2024" rel="noopener noreferrer"&gt;Treblle API Report 2024: Key Findings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://report.treblle.com/" rel="noopener noreferrer"&gt;Treblle Report Portal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nordicapis.com/shift-to-ai-exploded-api-usage-in-2024/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Nordic APIs: How AI Exploded API Usage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.postman.com/state-of-api/2024/api-global-growth/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Postman State of APIs 2024&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gartner.com/en/newsroom/press-releases/2024-03-20-gartner-predicts-more-than-30-percent-of-the-increase-in-demand-for-apis-will-come-from-ai-and-tools-using-llms-by-2026" rel="noopener noreferrer"&gt;Gartner on API Growth Through AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.precedenceresearch.com/api-management-market?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Precedence Research: API Management Market&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel Free to download the reports and go through articles to understand more about the API growth over the time.&lt;/p&gt;




&lt;h2&gt;
  
  
  APIs Are Growing—A Lot
&lt;/h2&gt;

&lt;p&gt;Across the board, all these reports make one thing clear: &lt;strong&gt;the API space is growing fast&lt;/strong&gt;, and a big reason for that is the rapid rise of AI.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;As per the &lt;a href="https://nordicapis.com/20-impressive-api-economy-statistics/" rel="noopener noreferrer"&gt;Nordic APIs article&lt;/a&gt; and &lt;a href="https://blog.treblle.com/the-anatomy-of-an-api-in-2023-a-comprehensive-overview/" rel="noopener noreferrer"&gt;Treblle&lt;/a&gt;, 83% of All Internet Traffic Belongs to API-Based Services.&lt;/li&gt;
&lt;li&gt;As per &lt;a href="https://www.imperva.com/resources/resource-library/reports/the-state-of-api-security-in-2024/" rel="noopener noreferrer"&gt;Imperva&lt;/a&gt;, a Thales company, quotes 'API calls make up a massive 71% of all web traffic'.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These all reports very clearly mention that APIs are growing drastically. &lt;/p&gt;

&lt;p&gt;Some other stats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Postman users grew by 40%.&lt;/strong&gt;
&lt;a href="https://www.postman.com/state-of-api/2024/api-global-growth/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Source – Postman State of API 2024&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AsyncAPI downloads jumped by 240% in 2023.&lt;/strong&gt;
&lt;a href="https://www.asyncapi.com/blog/2023-summary?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Source – AsyncAPI 2023 Summary&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API-first development is up by 74%.&lt;/strong&gt;
&lt;a href="https://www.infoworld.com/article/3578704/developers-embracing-api-first-development-survey-says.html?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Source – InfoWorld&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So both AI-related and non-AI APIs are growing, but the AI ones? They’re blowing up.&lt;/p&gt;

&lt;p&gt;Graphical data from Treblle, showing the AI related API growth:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbg6l1jze9mv19yfgae7q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbg6l1jze9mv19yfgae7q.png" alt="Graphical data from Treblle, showing the AI related API growth" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Recap: What Are APIs and AI APIs?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is an API?
&lt;/h3&gt;

&lt;p&gt;APIs (Application Programming Interfaces) are basically bridges—sets of tools and protocols that let different apps talk to each other, safely and efficiently. They’re what glue the digital world together.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is AI?
&lt;/h3&gt;

&lt;p&gt;AI (Artificial Intelligence) is all about machines mimicking human intelligence—understanding text, images, sound, and making decisions or predictions based on that.&lt;/p&gt;

&lt;h3&gt;
  
  
  And AI-related APIs?
&lt;/h3&gt;

&lt;p&gt;These are APIs that &lt;strong&gt;bring AI features&lt;/strong&gt; into apps. Think: language understanding, image recognition, voice processing, etc.—all made easily accessible via simple API calls. No need to build complex models from scratch.&lt;/p&gt;




&lt;h2&gt;
  
  
  So Why Is AI Driving API Growth?
&lt;/h2&gt;

&lt;p&gt;Honestly, I think it’s a two-way street—&lt;strong&gt;AI and APIs are helping each other grow&lt;/strong&gt;. Here's why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI models need lots of data, and APIs are a major way to get that data.&lt;/li&gt;
&lt;li&gt;Most AI services expose their capabilities through APIs—makes tracking, scaling, and integration much easier.&lt;/li&gt;
&lt;li&gt;APIs make it super simple to plug AI features into apps, products, or services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So naturally, as AI adoption grows, so does the demand for APIs.&lt;br&gt;
Check out some graphs that depicts the API growth in past few years.&lt;/p&gt;




&lt;h2&gt;
  
  
  But It’s Not All Smooth Sailing
&lt;/h2&gt;

&lt;p&gt;One thing several reports pointed out—and something I’ve seen firsthand—is that &lt;strong&gt;a lot of APIs are poorly documented or managed&lt;/strong&gt;. This slows everything down.&lt;/p&gt;

&lt;p&gt;Developers end up spending too much time figuring out how an API works instead of actually building things. And with the pace we’re moving at, that’s a problem.&lt;/p&gt;

&lt;p&gt;That’s why I was glad to see some cool AI tools popping up to solve this—&lt;strong&gt;&lt;a href="https://hexmos.com/landing/liveapi/" rel="noopener noreferrer"&gt;LiveAPI&lt;/a&gt;&lt;/strong&gt; is one I came across that looks promising. It’s designed to help developers better understand, manage, and work with APIs more efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're working with APIs, I’d highly recommend checking it out. Go try it—it might really boost your productivity!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping It Up
&lt;/h2&gt;

&lt;p&gt;2024 is clearly a breakout year for APIs. A few quick highlights:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We’re now looking at &lt;strong&gt;15,000+ APIs&lt;/strong&gt;, &lt;strong&gt;500,000+ endpoints&lt;/strong&gt;, and over &lt;strong&gt;1 billion API requests&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;average API now has 42 endpoints&lt;/strong&gt;, nearly double from last year&lt;/li&gt;
&lt;li&gt;Large enterprises are managing &lt;strong&gt;1,000+ APIs&lt;/strong&gt;, mostly for internal use&lt;/li&gt;
&lt;li&gt;And &lt;strong&gt;AI-related APIs? They grew by a whopping 807%&lt;/strong&gt;—compared to 10% growth in other API sectors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't just about tech—it’s about how businesses operate and scale. APIs are at the heart of digital transformation, and with AI in the mix, that momentum is only picking up.&lt;/p&gt;

&lt;p&gt;Big players like Amazon, Google, Salesforce, and Meta are a great example—they’ve deeply embedded APIs and AI into their products and operations, and it shows in their growth and market dominance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;APIs are no longer just backend utilities—they’re &lt;strong&gt;core to modern business&lt;/strong&gt;. They enable speed, scalability, security, and innovation. And in this AI-driven world, &lt;strong&gt;getting APIs right is crucial&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you’re working in tech today, understanding and leveraging APIs (especially AI-driven ones) isn’t just useful—it’s essential.&lt;/p&gt;




</description>
      <category>api</category>
      <category>ai</category>
      <category>liveapi</category>
      <category>programming</category>
    </item>
    <item>
      <title>Digging Deeper into Code with Tree-Sitter: How to Query Your Syntax Tree</title>
      <dc:creator>Shailendra Kumar Gupta</dc:creator>
      <pubDate>Wed, 14 May 2025 00:30:48 +0000</pubDate>
      <link>https://forem.com/shailendra53/digging-deeper-into-code-with-tree-sitter-how-to-query-your-syntax-tree-3i1</link>
      <guid>https://forem.com/shailendra53/digging-deeper-into-code-with-tree-sitter-how-to-query-your-syntax-tree-3i1</guid>
      <description>&lt;p&gt;Hello everyone! I'm Shailendra.&lt;br&gt;
In my last post — &lt;a href="https://dev.to/shailendra53/tree-sitter-from-code-to-syntax-tree-45op"&gt;'Tree-Sitter: From Code to Syntax-Tree'&lt;/a&gt; — I talked about how we can use Tree-sitter to generate a syntax tree for a given language using its grammar.&lt;/p&gt;

&lt;p&gt;In this post, we’ll go one step further and see how Tree-sitter can be used to make queries on your source text to understand and analyze various parts of the code.&lt;/p&gt;

&lt;p&gt;This is another very interesting feature of Tree-sitter that can help you get deeper insights into your source code. For example, you can write a query to list all the functions present in a repo's source code. And that's exactly what we’ll explore in this post.&lt;/p&gt;

&lt;p&gt;Just like the last post, I’ll use GoLang for demonstrating the use cases. If you’re not familiar with how to use Tree-sitter in GoLang, please check the previous post for installation steps and the basic code setup.&lt;/p&gt;


&lt;h2&gt;
  
  
  Our Use Case
&lt;/h2&gt;

&lt;p&gt;Now, let’s get into our use case. As mentioned, I’ll demonstrate how to list all the functions from a given source file.&lt;/p&gt;

&lt;p&gt;Here’s the GoLang code we’ll be analyzing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"+"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;subtract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unknown operator"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Parse Tree Output
&lt;/h2&gt;

&lt;p&gt;Let’s quickly look at how the parse tree would look for this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(source_file
  (package_clause
    (package_identifier))

  (import_declaration
    (import_spec
      path: (interpreted_string_literal)))

  (function_declaration
    name: (identifier)
    parameters: (parameter_list
      (parameter_declaration
        name: (identifier)
        type: (type_identifier))
      (parameter_declaration
        name: (identifier)
        type: (type_identifier)))
    result: (type_identifier)
    body: (block
      (return_statement
        (expression_list
          (binary_expression
            left: (identifier)
            right: (identifier))))))

  (function_declaration
    name: (identifier)
    parameters: (parameter_list
      (parameter_declaration
        name: (identifier)
        name: (identifier)
        type: (type_identifier)))
    result: (type_identifier)
    body: (block
      (return_statement
        (expression_list
          (binary_expression
            left: (identifier)
            right: (identifier))))))

  (function_declaration
    name: (identifier)
    parameters: (parameter_list
      (parameter_declaration
        name: (identifier)
        type: (type_identifier))
      (parameter_declaration
        name: (identifier)
        name: (identifier)
        type: (type_identifier)))
    result: (type_identifier)
    body: (block
      (expression_switch_statement
        value: (identifier)

        (expression_case
          value: (expression_list
            (interpreted_string_literal))
          (return_statement
            (expression_list
              (call_expression
                function: (identifier)
                arguments: (argument_list
                  (identifier)
                  (identifier))))))

        (expression_case
          value: (expression_list
            (interpreted_string_literal))
          (return_statement
            (expression_list
              (call_expression
                function: (identifier)
                arguments: (argument_list
                  (identifier)
                  (identifier))))))

        (default_case
          (expression_statement
            (call_expression
              function: (selector_expression
                operand: (identifier)
                field: (field_identifier))
              arguments: (argument_list
                (interpreted_string_literal))))))

      (return_statement
        (expression_list
          (unary_expression
            operand: (int_literal))))))
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the parameters in the &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;subtract&lt;/code&gt; functions are presented differently. That’s because Go allows you to group parameters with the same type, and Tree-sitter reflects that nicely in the syntax tree.&lt;/p&gt;




&lt;h2&gt;
  
  
  Printing the Syntax Tree
&lt;/h2&gt;

&lt;p&gt;Here’s the main code that prints the above Tree-sitter output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;

    &lt;span class="n"&gt;tree_sitter&lt;/span&gt; &lt;span class="s"&gt;"github.com/smacker/go-tree-sitter"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/smacker/go-tree-sitter/golang"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tree_sitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetLanguage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;golang&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetLanguage&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.go"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseCtx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RootNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Root type:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Tree:
"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The source code above is part of the &lt;code&gt;example.go&lt;/code&gt; file.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Querying Function Names
&lt;/h2&gt;

&lt;p&gt;Now, let’s try to capture all the function names in the source. To do this, we’ll provide a query that matches all the function names in the syntax tree.&lt;/p&gt;

&lt;p&gt;A function node looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function_declaration
    name: (identifier)
    parameters: (parameter_list)
    result: (type_identifier)
    body: (block)
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To extract just the function name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function_declaration
    name: (identifier) @function-name
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Code for this query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;

    &lt;span class="n"&gt;tree_sitter&lt;/span&gt; &lt;span class="s"&gt;"github.com/smacker/go-tree-sitter"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/smacker/go-tree-sitter/golang"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;function_declarations_query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;`
        (function_declaration
            name: (identifier) @function-name
        )
    `&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tree_sitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetLanguage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;golang&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetLanguage&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"example.go"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseCtx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tree_sitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewQuery&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function_declarations_query&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;golang&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetLanguage&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tree_sitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewQueryCursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RootNode&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextMatch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capture&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Captures&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;capture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Found function:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Output:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go run main.go 
Found function: add
Found function: subtract
Found function: calculator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Querying Parameters as Well
&lt;/h2&gt;

&lt;p&gt;To print the parameters as well, update the query like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(function_declaration
    name: (identifier) @function-name
    parameters: (parameter_list) @parameter-list
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We just added this:&lt;br&gt;
&lt;code&gt;parameters: (parameter_list) @parameter-list&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Output:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go run main.go 
Found function: add
Parameters list: (num1 int32, num2 int32)
Found function: subtract
Parameters list: (num1, num2 int32)
Found function: calculator
Parameters list: (operator string, num1, num2 int32)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Hope this helps clarify how we can use queries in Tree-sitter to analyze different parts of the code. I encourage you to explore more by experimenting with different queries and observing the output. That’s the best way to understand how Tree-sitter represents various parts of source code using syntax tree nodes.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔔 Important Note
&lt;/h2&gt;

&lt;p&gt;Before we wrap up — if you’re someone who’s tired of wasting time searching and trying to understand internal APIs, do check out the AI tool &lt;strong&gt;&lt;a href="https://hexmos.com/landing/liveapi/" rel="noopener noreferrer"&gt;LiveAPI&lt;/a&gt;&lt;/strong&gt;. It’s a pretty handy tool for working with internal APIs in large codebases.&lt;/p&gt;

&lt;p&gt;LiveAPI helps you &lt;strong&gt;discover&lt;/strong&gt;, &lt;strong&gt;understand&lt;/strong&gt;, and &lt;strong&gt;use&lt;/strong&gt; APIs within big tech infrastructures.&lt;br&gt;&lt;br&gt;
Ease your API life with LiveAPI.&lt;/p&gt;




</description>
      <category>go</category>
      <category>treesitter</category>
      <category>parser</category>
      <category>learning</category>
    </item>
    <item>
      <title>Tree-Sitter: From Code to Syntax-Tree</title>
      <dc:creator>Shailendra Kumar Gupta</dc:creator>
      <pubDate>Sun, 11 May 2025 20:21:37 +0000</pubDate>
      <link>https://forem.com/shailendra53/tree-sitter-from-code-to-syntax-tree-45op</link>
      <guid>https://forem.com/shailendra53/tree-sitter-from-code-to-syntax-tree-45op</guid>
      <description>&lt;p&gt;I’m Shailendra, and in this article, I’m going to talk about a very interesting tool called Tree-sitter. I recently came across this tool while going through another interesting tool for APIs: &lt;a href="https://hexmos.com/landing/liveapi/" rel="noopener noreferrer"&gt;LiveAPI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As per the definition, Tree-sitter is a parse generator tool and an increment parsing library.&lt;/p&gt;

&lt;p&gt;Let’s understand what we mean by these terms. I’m sure many of you already know about it but just to make sure everyone understands, let’s describe them quickly.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Parse Generator Tool&lt;/strong&gt;: These are the tools that automates the process of developing/creating parser (a component that analyses the syntactical correctness of a language and throws appropriate errors). One can avoid the manual work of writing parsers, by providing grammar specifications to such tools. The tool automatically translates it into a parser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Input: Grammar for a language.&lt;br&gt;
Output: A parser that can analyze texts for specified grammar.&lt;br&gt;
Some other examples of parser generator tools: YACC (Yet Another Compiler Compiler), JavaCC (Java Compiler Compiler), Lark, etc.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Increment parsing library&lt;/strong&gt;: This means that Tree-sitter efficiently parses the code by ONLY analysing the changed/modified part of the source file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, that we know what about Tree-sitter. Let’s try to see it in action to understand how we can use it.&lt;br&gt;
I’ll use GoLang to demonstrate my learnings about the tool. Also, I’ll use the same language parser to show the usages of this tool. However, the tool is supported on multiple languages. Feel free to use the learnings from here and apply it to your specific language.&lt;/p&gt;

&lt;p&gt;There are two ways in which we can install for use.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the source from git and compile for use. &lt;a href="https://github.com/tree-sitter/tree-sitter-go" rel="noopener noreferrer"&gt;Tree-sitter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GoLang wrapper libraries to ease your life. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'll use second method as part of this article. Use below commands to download and install the dependencies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the tree-sitter library for GoLang.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/smacker/go-tree-sitter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Download the GoLang parser.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/smacker/go-tree-sitter/go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let’s analyse a basic GoLang code using tree-sitter.&lt;br&gt;
GoLang code that we are going to analyse:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func add(num1 int, num2 int) {
    return num1 + num2 * 3
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Main code for analysing the source text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "context"
    "fmt"
    "log"

    tree_sitter "github.com/smacker/go-tree-sitter"
    "github.com/smacker/go-tree-sitter/golang"
)

var (
    source_text = `
        func add(num1 int, num2 int) {
            return num1 + num2 * 3
        }
    `
)

func main() {
    parser := tree_sitter.NewParser()
    parser.SetLanguage(golang.GetLanguage())

    code := []byte(source_text)
    tree, err := parser.ParseCtx(context.Background(), nil, code)
    if err != nil {
        log.Fatal(err)
    }

    root := tree.RootNode()
    fmt.Println("Root type:", root.Type())
    fmt.Println("Tree:\n", root.String())
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go run main.go
Root type: source_file
Tree:
 (source_file (function_declaration name: (identifier) parameters: (parameter_list (parameter_declaration name: (identifier) type: (type_identifier)) (parameter_declaration name: (identifier) type: (type_identifier))) body: (block (return_statement (expression_list (binary_expression left: (identifier) right: (binary_expression left: (identifier) right: (int_literal))))))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's understand the output of the program. Tree-sitter gives output in the form of a syntax tree representing different parts of the text with root as the source file (containing the text).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source_file
└── function_declaration
    ├── name: identifier
    ├── parameters: parameter_list
    │   ├── parameter_declaration
    │   │   ├── name: identifier
    │   │   └── type: type_identifier
    │   └── parameter_declaration
    │       ├── name: identifier
    │       └── type: type_identifier
    └── body: block
        └── return_statement
            └── expression_list
                └── binary_expression
                    ├── left: identifier
                    └── right: binary_expression
                        ├── left: identifier
                        └── right: int_literal


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the input text, a programmer can understand that the input text is GoLang program representing as follows:&lt;br&gt;
1. A single function.&lt;br&gt;
2. Taking 2 integers as input.&lt;br&gt;
3. Summing them up after multiplying num2 by 3.&lt;br&gt;
4. returns the calculated value.&lt;/p&gt;

&lt;p&gt;The Tree-sitter tool also outputs the same. It doesn’t prints the different identifiers and their names, as they are not required for syntax parsing. It just differentiates various parts of the text and related them as per the language grammar. The same you can see from the readable output of the Tree-sitter.&lt;/p&gt;

&lt;p&gt;This shows how Tree-sitter uses a language grammar and analyses the source text. This can help you to understand whether a given set of source files follows your language grammar or not? In case of programmer languages, you can take Tree-sitter helps to verify the same without compiling all your source codes. Also, note that you do not need compilers to be installed for such analysis.&lt;/p&gt;

&lt;p&gt;Hope this clarifies a use-case of this tool. Apart from this, there a lot of interesting use-cases for this tool. Some of them I'll try to cover in future posts. For more details on the tool you can refer the website: &lt;a href="https://tree-sitter.github.io/tree-sitter/" rel="noopener noreferrer"&gt;Tree-sitter&lt;/a&gt;&lt;br&gt;
Also, do watch this interesting video of &lt;a href="https://youtu.be/Jes3bD6P0To?si=igtSRMoX5ioDM8nL" rel="noopener noreferrer"&gt;Tree-sitter:YouTube&lt;/a&gt; which helped me to understand the basic of it.&lt;/p&gt;

&lt;p&gt;IMPORTANT NOTE:&lt;br&gt;
BTW, before we wrap-up. If you are a person tired of wasting time on searching and understanding your internal APIs, do check the AI tool &lt;a href="https://hexmos.com/landing/liveapi/" rel="noopener noreferrer"&gt;LiveAPI&lt;/a&gt;. It is an interesting AI tool for all your internal APIs. LiveAPI helps you discover, understand and use APIs in large tech infrastructures. Ease your API life with LiveAPI.&lt;/p&gt;

</description>
      <category>treesitter</category>
      <category>go</category>
      <category>syntaxtree</category>
      <category>parser</category>
    </item>
  </channel>
</rss>
