<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Air Pipe]]></title><description><![CDATA[Empowering developers & businesses to build APIs, workflows, & integrations in seconds. Fast, secure, and scalable. Tips on API dev, DevOps, & automation. #API ]]></description><link>https://blog.airpipe.io</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1727251230032/1966ea06-4a48-486d-b3a1-5349435c4686.png</url><title>Air Pipe</title><link>https://blog.airpipe.io</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 14:19:27 GMT</lastBuildDate><atom:link href="https://blog.airpipe.io/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Latency based container scaling with Orbit]]></title><description><![CDATA[Haven't read Part 1? Start with Building Orbit: A Lightweight Container Orchestrator in Rust to learn about our journey's beginning.

In our previous article, we introduced Orbit, our lightweight container orchestrator built in Rust. Since then, we'v...]]></description><link>https://blog.airpipe.io/latency-based-container-scaling-with-orbit</link><guid isPermaLink="true">https://blog.airpipe.io/latency-based-container-scaling-with-orbit</guid><category><![CDATA[Rust]]></category><category><![CDATA[containers]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Developer]]></category><category><![CDATA[backend]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Microservices]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Kav Pather]]></dc:creator><pubDate>Mon, 17 Feb 2025 15:01:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1739802952034/99fe2c1d-17b5-450d-a705-f4888a78cc11.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>Haven't read Part 1? Start with <a target="_blank" href="https://blog.airpipe.io/building-orbit-a-lightweight-container-orchestration-tool-in-rust">Building Orbit: A Lightweight Container Orchestrator in Rust</a> to learn about our journey's beginning.</p>
</blockquote>
<p>In our previous article, we introduced Orbit, our lightweight container orchestrator built in Rust. Since then, we've made significant improvements driven by both community feedback and production requirements. Let's dive into the technical evolution that's making Orbit even more powerful and efficient.</p>
<h2 id="heading-community-driven-development">Community-Driven Development</h2>
<p>One of the most exciting aspects of Orbit's development has been the community engagement. A perfect example is our implementation of <a target="_blank" href="https://en.wikipedia.org/wiki/CoDel">CoDel (Controlled Delay)</a> for scaling decisions, which came directly from a community member's suggestion on Medium. We're also grateful to community members like <a target="_blank" href="https://github.com/josselinchevalay">Josselin Chevalay</a> who contributed the <code>pull_policy</code> feature in our latest release, allowing control over container image pulling behavior. This collaborative approach will continue to help shape Orbit's feature set and technical direction.</p>
<h2 id="heading-technical-evolution-key-improvements">Technical Evolution: Key Improvements</h2>
<h3 id="heading-1-codel-controlled-delay-inspired-scaling-latency-driven-container-orchestration">1. CoDel (Controlled Delay) - Inspired Scaling: Latency-Driven Container Orchestration</h3>
<p>Unlike traditional orchestrators that rely solely on CPU and memory metrics, we've implemented <a target="_blank" href="https://en.wikipedia.org/wiki/CoDel">CoDel-based/inspired scaling</a> - a feature not natively available in Kubernetes or other major orchestrators. Here's how it works:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">CoDelMetrics</span></span> {
    service_name: <span class="hljs-built_in">String</span>,
    sojourn_times: VecDeque&lt;(Instant, Duration)&gt;,
    first_above_time: <span class="hljs-built_in">Option</span>&lt;Instant&gt;,
    last_scale_time: Instant,
    config: CoDelConfig,
}
</code></pre>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">adaptive-scaling</span>
<span class="hljs-attr">instance_count:</span>
  <span class="hljs-attr">min:</span> <span class="hljs-number">2</span>
  <span class="hljs-attr">max:</span> <span class="hljs-number">10</span>

<span class="hljs-comment"># CoDel-inspired adaptive scaling based on request latency</span>
<span class="hljs-attr">codel:</span>
  <span class="hljs-attr">target:</span> <span class="hljs-string">100ms</span>                   <span class="hljs-comment"># Target latency threshold</span>
  <span class="hljs-attr">interval:</span> <span class="hljs-string">1s</span>                    <span class="hljs-comment"># Interval for checking delays</span>
  <span class="hljs-attr">consecutive_intervals:</span> <span class="hljs-number">3</span>        <span class="hljs-comment"># Number of intervals above target before scaling</span>
  <span class="hljs-attr">max_scale_step:</span> <span class="hljs-number">1</span>              <span class="hljs-comment"># Maximum instances to scale up at once</span>
  <span class="hljs-attr">scale_cooldown:</span> <span class="hljs-string">30s</span>            <span class="hljs-comment"># Minimum time between scaling actions</span>
  <span class="hljs-attr">overload_status_code:</span> <span class="hljs-number">503</span>      <span class="hljs-comment"># Return 503 when overloaded</span>

<span class="hljs-comment"># Fine-tune scaling behavior</span>
<span class="hljs-attr">scaling_policy:</span>
  <span class="hljs-attr">cooldown_duration:</span> <span class="hljs-string">60s</span>         <span class="hljs-comment"># Wait time between scaling actions</span>
  <span class="hljs-attr">scale_down_threshold_percentage:</span> <span class="hljs-number">50.0</span>  <span class="hljs-comment"># Scale down if usage below 50%</span>

<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">containers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">main</span>
      <span class="hljs-attr">image:</span> <span class="hljs-string">airpipeio/infoapp:latest</span>
      <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
          <span class="hljs-attr">node_port:</span> <span class="hljs-number">4335</span>
</code></pre>
<p>The CoDel inspired implementation monitors request latency and makes intelligent scaling decisions based on both immediate and historical performance data. Benefits include:</p>
<ul>
<li><p>More responsive scaling based on actual service performance</p>
</li>
<li><p>Better handling of latency spikes</p>
</li>
<li><p>Prevention of unnecessary scale-ups during temporary load increases</p>
</li>
</ul>
<p><strong>Note</strong> that this is just our initial implementation, and we will continue to improve where possible and perhaps rename when appropriate.</p>
<p>Key Differences from Traditional CoDel:</p>
<ul>
<li><p><strong>Service-Level Application</strong>:</p>
<ul>
<li><p>Our implementation applies CoDel principles at the service level rather than packet level</p>
</li>
<li><p>Uses request latency instead of packet sojourn time</p>
</li>
<li><p>Focuses on scaling rather than packet dropping</p>
</li>
</ul>
</li>
<li><p><strong>State Management</strong>:</p>
<ul>
<li>This is simpler than traditional CoDel's state machine.</li>
</ul>
</li>
</ul>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">CoDelMetrics</span></span> {
    sojourn_times: VecDeque&lt;(Instant, Duration)&gt;,
    first_above_time: <span class="hljs-built_in">Option</span>&lt;Instant&gt;,
    last_scale_time: Instant,
}
</code></pre>
<h3 id="heading-2-health-monitoring">2. Health Monitoring</h3>
<p>We've added the usual health monitoring with TCP health checks:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">HealthCheckConfig</span></span> {
    <span class="hljs-keyword">pub</span> startup_timeout: Duration,
    <span class="hljs-keyword">pub</span> startup_failure_threshold: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> liveness_period: Duration,
    <span class="hljs-keyword">pub</span> liveness_failure_threshold: <span class="hljs-built_in">u32</span>,
    <span class="hljs-keyword">pub</span> tcp_check: <span class="hljs-built_in">Option</span>&lt;TcpHealthCheck&gt;,
}
</code></pre>
<p>This system provides:</p>
<ul>
<li><p>Configurable health check parameters</p>
</li>
<li><p>TCP-level connectivity verification</p>
</li>
<li><p>Granular control over failure thresholds</p>
</li>
<li><p>Separate startup and liveness checks</p>
</li>
</ul>
<h3 id="heading-3-performance-optimizations">3. Performance Optimizations</h3>
<p>We've made several low-level optimizations to improve performance:</p>
<h4 id="heading-switching-to-fxhashmapfxhashset">Switching to FxHashMap/FxHashSet</h4>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> rustc_hash::{FxHashMap, FxHashSet};

<span class="hljs-keyword">pub</span> <span class="hljs-keyword">static</span> INSTANCE_STORE: OnceLock&lt;
    Arc&lt;RwLock&lt;FxHashMap&lt;<span class="hljs-built_in">String</span>, FxHashMap&lt;Uuid, InstanceMetadata&gt;&gt;&gt;&gt;
&gt; = OnceLock::new();
</code></pre>
<p>By replacing standard HashMap with FxHashMap:</p>
<ul>
<li><p>Reduced memory overhead</p>
</li>
<li><p>Faster hash computation</p>
</li>
<li><p>Better performance for string keys</p>
</li>
<li><p>Lower collision rates in our specific use cases</p>
</li>
</ul>
<h3 id="heading-4-improved-resource-management">4. Improved Resource Management</h3>
<p>We've implemented a more sophisticated resource management system:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">ResourceThresholds</span></span> {
    <span class="hljs-keyword">pub</span> cpu_percentage: <span class="hljs-built_in">Option</span>&lt;<span class="hljs-built_in">u8</span>&gt;,
    <span class="hljs-keyword">pub</span> cpu_percentage_relative: <span class="hljs-built_in">Option</span>&lt;<span class="hljs-built_in">u8</span>&gt;,
    <span class="hljs-keyword">pub</span> memory_percentage: <span class="hljs-built_in">Option</span>&lt;<span class="hljs-built_in">u8</span>&gt;,
    <span class="hljs-keyword">pub</span> metrics_strategy: PodMetricsStrategy,
}
</code></pre>
<p>This allows for:</p>
<ul>
<li><p>Fine-grained control over resource utilization</p>
</li>
<li><p>Better handling of CPU quota management</p>
</li>
<li><p>More accurate memory tracking</p>
</li>
<li><p>Customizable metrics aggregation strategies</p>
</li>
</ul>
<h2 id="heading-real-world-impact">Real-World Impact</h2>
<p>These improvements have had significant real-world impact:</p>
<ul>
<li><p>30% reduction in unnecessary scaling operations</p>
</li>
<li><p>More stable performance under varying load conditions</p>
</li>
<li><p>Reduced resource usage in the orchestrator itself</p>
</li>
<li><p>Better handling of microservices with varying performance characteristics</p>
</li>
<li><p>Still managed to retain a &lt;5MB binary size footprint</p>
</li>
</ul>
<h2 id="heading-whats-next-decentralized-clustering">What's Next: Decentralized Clustering!?</h2>
<p>We're excited to explore our next major development focus: a decentralized clustering solution. This will allow Orbit to:</p>
<ul>
<li><p>Operate without a central control plane</p>
</li>
<li><p>Provide better resilience in edge deployments</p>
</li>
<li><p>Enable peer-to-peer node coordination</p>
</li>
<li><p>Support dynamic cluster topology changes</p>
</li>
</ul>
<p>We have some initial ideas on how to design the solution, so please follow for our next update to see how we hope to make this happen!</p>
<h2 id="heading-building-at-scale-with-air-pipe">Building at Scale with Air Pipe</h2>
<p>While Orbit handles container orchestration, it's just one piece of the puzzle. At <a target="_blank" href="https://airpipe.io">Air Pipe</a>, we're building a comprehensive platform for creating scalable, resilient APIs, integrations, and workflows. Our platform enables you to:</p>
<ul>
<li><p>Build and deploy scalable APIs with minimal boilerplate</p>
</li>
<li><p>Create robust integration workflows</p>
</li>
<li><p>Implement resilient data processing pipelines</p>
</li>
<li><p>Leverage edge computing capabilities</p>
</li>
</ul>
<p>If you're building distributed systems or scalable applications, visit <a target="_blank" href="https://airpipe.io">airpipe.io</a> to learn how our platform can accelerate your development.</p>
<h2 id="heading-get-involved">Get Involved</h2>
<p>We're building Orbit in the open and value community input. Whether you're interested in the technical details or want to contribute to our upcoming clustering features:</p>
<ul>
<li><p>Star us on <a target="_blank" href="https://github.com/airpipeio/orbit">GitHub</a></p>
</li>
<li><p>Join our <a target="_blank" href="https://discord.com/invite/b8mFtjWXZj">Discord community</a></p>
</li>
<li><p>Visit <a target="_blank" href="https://airpipe.io">Air Pipe</a></p>
</li>
<li><p>Follow our progress as we build the decentralized clustering solution</p>
</li>
</ul>
<p>Stay tuned for our next technical deep-dive where we'll explore the architecture of our decentralized clustering approach!</p>
]]></content:encoded></item><item><title><![CDATA[Building Orbit: A Lightweight Container Orchestration Tool in Rust]]></title><description><![CDATA[At Air Pipe, we faced a common challenge in the world of container orchestration - finding the right balance between functionality and complexity. While Kubernetes offers a powerful but complex solution, and Docker Swarm lacks crucial features like a...]]></description><link>https://blog.airpipe.io/building-orbit-a-lightweight-container-orchestration-tool-in-rust</link><guid isPermaLink="true">https://blog.airpipe.io/building-orbit-a-lightweight-container-orchestration-tool-in-rust</guid><category><![CDATA[Rust]]></category><category><![CDATA[containers]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Developer]]></category><category><![CDATA[backend]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Microservices]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Kav Pather]]></dc:creator><pubDate>Thu, 30 Jan 2025 14:43:20 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738246270633/d863e6a3-744b-4ada-810f-3f8273d4cc6d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>At <a target="_blank" href="https://airpipe.io/">Air Pipe</a>, we faced a common challenge in the world of container orchestration - finding the right balance between functionality and complexity. While Kubernetes offers a powerful but complex solution, and Docker Swarm lacks crucial features like autoscaling, we needed something that fit perfectly in the middle. We decided to build <a target="_blank" href="https://github.com/AirPipeIO/orbit">Orbit</a>, a lightweight container orchestration tool written in Rust that we're actively developing and improving.</p>
<blockquote>
<p><strong>Update</strong>: Check out <a target="_blank" href="https://blog.airpipe.io/latency-based-container-scaling-with-orbit">Part 2 of this series</a> where we explore Orbit's evolution including latency-based container scaling, TCP health checks, and performance optimizations.</p>
</blockquote>
<h2 id="heading-why-we-started">Why We Started</h2>
<p>Our journey began with a specific need at Air Pipe. Running a shared-nothing architecture at the edge, we needed a simple way to scale HTTP/TCP based containers without the overhead of complex infrastructure or additional dependencies. We wanted something that could be deployed as a single binary, yet provide robust container management capabilities.</p>
<p>The existing solutions didn't quite fit:</p>
<ul>
<li><p>Kubernetes: Too complex for our edge use case, with a large learning curve and resource footprint</p>
</li>
<li><p>Docker Swarm: Too basic, lacking crucial features like autoscaling</p>
</li>
<li><p>Other solutions: Either too complex or too tightly coupled with specific cloud providers or vendors</p>
</li>
</ul>
<h2 id="heading-starting-simple-basic-container-management">Starting Simple: Basic Container Management</h2>
<p>We started with the basics - a simple Rust application that could manage individual containers. The choice of Rust was deliberate:</p>
<ul>
<li><p>Memory safety without garbage collection</p>
</li>
<li><p>High performance and low resource usage</p>
</li>
<li><p>Strong type system and excellent concurrency model</p>
</li>
<li><p>Growing ecosystem of libraries and tools</p>
</li>
</ul>
<p>Our first version could do basic container operations:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">start_containers</span></span>(
    &amp;<span class="hljs-keyword">self</span>,
    service_name: &amp;<span class="hljs-built_in">str</span>,
    containers: &amp;<span class="hljs-built_in">Vec</span>&lt;Container&gt;,
) -&gt; <span class="hljs-built_in">Result</span>&lt;<span class="hljs-built_in">Vec</span>&lt;(<span class="hljs-built_in">String</span>, <span class="hljs-built_in">String</span>)&gt;&gt; {
    <span class="hljs-comment">// Basic container startup logic</span>
}
</code></pre>
<h2 id="heading-evolution-to-pod-based-architecture">Evolution to Pod-Based Architecture</h2>
<p>As we developed the system, we realized that managing groups of containers together (pods) would provide better isolation and resource management. This led to a more sophisticated container management system:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">pub</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">InstanceMetadata</span></span> {
    <span class="hljs-keyword">pub</span> uuid: Uuid,
    <span class="hljs-keyword">pub</span> created_at: SystemTime,
    <span class="hljs-keyword">pub</span> network: <span class="hljs-built_in">String</span>,
    <span class="hljs-keyword">pub</span> containers: <span class="hljs-built_in">Vec</span>&lt;ContainerMetadata&gt;,
    <span class="hljs-keyword">pub</span> image_hash: HashMap&lt;<span class="hljs-built_in">String</span>, <span class="hljs-built_in">String</span>&gt;,
}
</code></pre>
<p>This structure allowed us to track related containers and their metadata together, making operations like scaling and updates more coherent.</p>
<h2 id="heading-the-game-changer-integrating-pingora">The Game Changer: Integrating Pingora</h2>
<p>One of our most significant technical decisions was choosing <a target="_blank" href="https://blog.cloudflare.com/pingora-open-source/">Cloudflare's Pingora</a> framework for our proxy layer. This wasn't just about load balancing - it was about building a robust, high-performance proxy system that could handle production workloads efficiently.</p>
<p>Why Pingora?</p>
<ul>
<li><p>Written in Rust, aligning with our technology stack</p>
</li>
<li><p>Battle-tested at Cloudflare's scale</p>
</li>
<li><p>Excellent performance characteristics</p>
</li>
<li><p>Built-in health checking and automatic failover</p>
</li>
</ul>
<p>The integration looked something like this:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">web-service</span>
<span class="hljs-attr">instance_count:</span>
  <span class="hljs-attr">min:</span> <span class="hljs-number">2</span>
  <span class="hljs-attr">max:</span> <span class="hljs-number">5</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">containers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">web</span>
      <span class="hljs-attr">image:</span> <span class="hljs-string">airpipeio/infoapp:latest</span>
      <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
          <span class="hljs-attr">node_port:</span> <span class="hljs-number">30080</span>  <span class="hljs-comment"># This enables Pingora proxy</span>
</code></pre>
<h2 id="heading-adding-intelligence-resource-based-autoscaling">Adding Intelligence: Resource-Based Autoscaling</h2>
<p>One of our proudest features is the intelligent autoscaling system. Instead of just scaling based on simple metrics, we implemented a sophisticated resource monitoring and scaling system:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">resource_thresholds:</span>
  <span class="hljs-attr">cpu_percentage:</span> <span class="hljs-number">80</span>         <span class="hljs-comment"># CPU usage threshold</span>
  <span class="hljs-attr">cpu_percentage_relative:</span> <span class="hljs-number">90</span> <span class="hljs-comment"># CPU usage relative to limit</span>
  <span class="hljs-attr">memory_percentage:</span> <span class="hljs-number">85</span>      <span class="hljs-comment"># Memory usage threshold</span>
  <span class="hljs-attr">metrics_strategy:</span> <span class="hljs-string">max</span>      <span class="hljs-comment"># Strategy for pod metrics</span>
</code></pre>
<p>The system continuously monitors these metrics and makes scaling decisions based on configurable thresholds. Here's a practical example:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">demo-service</span>
<span class="hljs-attr">instance_count:</span>
  <span class="hljs-attr">min:</span> <span class="hljs-number">2</span>
  <span class="hljs-attr">max:</span> <span class="hljs-number">5</span>
<span class="hljs-attr">memory_limit:</span> <span class="hljs-string">"1Gi"</span>
<span class="hljs-attr">cpu_limit:</span> <span class="hljs-string">"1.0"</span>
<span class="hljs-attr">resource_thresholds:</span>
  <span class="hljs-attr">cpu_percentage:</span> <span class="hljs-number">80</span>
  <span class="hljs-attr">memory_percentage:</span> <span class="hljs-number">85</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">containers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">infoapp</span>
      <span class="hljs-attr">image:</span> <span class="hljs-string">airpipeio/infoapp:latest</span>
      <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
          <span class="hljs-attr">node_port:</span> <span class="hljs-number">30080</span>
      <span class="hljs-attr">memory_limit:</span> <span class="hljs-string">"512Mi"</span>
      <span class="hljs-attr">cpu_limit:</span> <span class="hljs-string">"0.5"</span>
</code></pre>
<p>In this configuration, if CPU usage exceeds 80% or memory usage exceeds 85% across instances, Orbit automatically scales up the service (up to the max instance count). When resource usage decreases, it scales down gracefully while maintaining the minimum instance count.</p>
<h2 id="heading-where-we-are-today">Where We Are Today</h2>
<p>Today, Orbit stands as a testament to what's possible when you focus on solving a specific problem well. It's a single binary under 5MB that provides:</p>
<ul>
<li><p>Automated container scaling</p>
</li>
<li><p>Service discovery</p>
</li>
<li><p>High-performance proxying</p>
</li>
<li><p>Volume management</p>
</li>
<li><p>Rolling updates</p>
</li>
<li><p>Prometheus metrics integration</p>
</li>
</ul>
<h2 id="heading-try-it-yourself">Try It Yourself</h2>
<p>Want to see Orbit in action? Here's a simple example to get started:</p>
<ol>
<li><p><a target="_blank" href="https://github.com/AirPipeIO/orbit/releases">Download Orbit from our releases</a></p>
</li>
<li><p>Create a configuration file (e.g., <code>web-service.yml</code>):</p>
</li>
</ol>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">web-service</span>
<span class="hljs-attr">instance_count:</span>
  <span class="hljs-attr">min:</span> <span class="hljs-number">2</span>
  <span class="hljs-attr">max:</span> <span class="hljs-number">5</span>
<span class="hljs-attr">resource_thresholds:</span>
  <span class="hljs-attr">cpu_percentage:</span> <span class="hljs-number">80</span>
  <span class="hljs-attr">memory_percentage:</span> <span class="hljs-number">85</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">containers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">web</span>
      <span class="hljs-attr">image:</span> <span class="hljs-string">airpipeio/infoapp:latest</span>
      <span class="hljs-attr">ports:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">port:</span> <span class="hljs-number">80</span>
          <span class="hljs-attr">node_port:</span> <span class="hljs-number">30080</span>
</code></pre>
<ol start="3">
<li>Start Orbit: <code>orbit -c /path/to/configs</code></li>
</ol>
<p>Visit <a target="_blank" href="http://localhost:30080"><code>http://localhost:30080</code></a> to see your service in action, and watch <a target="_blank" href="https://github.com/AirPipeIO/orbit">Orbit</a> automatically manage scaling based on resource usage.</p>
<h2 id="heading-looking-forward">Looking Forward</h2>
<p>We're continuing to evolve <a target="_blank" href="https://github.com/AirPipeIO/orbit">Orbit</a> based on real-world usage and community feedback. Our focus remains on maintaining simplicity while adding powerful features that make container orchestration easier and more efficient.</p>
<p>Want to learn more or contribute? Check out our <a target="_blank" href="https://github.com/airpipeio/orbit">GitHub repository</a> or join our <a target="_blank" href="https://discord.com/invite/b8mFtjWXZj">Discord community</a>.</p>
<blockquote>
<p><strong>Continue Reading</strong>: Explore <a target="_blank" href="https://blog.airpipe.io/latency-based-container-scaling-with-orbit">Part 2 of this series</a> to see how Orbit has evolved with new features like latency-based scaling and performance optimizations.</p>
</blockquote>
<h2 id="heading-about-air-pipe">About Air Pipe</h2>
<p><a target="_blank" href="https://github.com/AirPipeIO/orbit">Orbit</a> is just one piece of the puzzle in our mission to simplify and improve the software development lifecycle. At <a target="_blank" href="https://airpipe.io">Air Pipe</a>, we're building tools and platforms that make it easier to build, test, and deploy applications. Our shared-nothing architecture and edge computing approach allows for highly efficient and scalable deployments.</p>
<p>Want to learn more about how <a target="_blank" href="https://airpipe.io">Air Pipe</a> can help streamline your development workflow? Visit <a target="_blank" href="http://airpipe.io">airpipe.io</a> to discover our complete suite of development tools and solutions. See how our platform can help you build better software, faster.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Visit <a target="_blank" href="https://airpipe.io">Air Pipe</a></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Find us on <a target="_blank" href="https://discord.com/invite/b8mFtjWXZj">Discord</a></div>
</div>]]></content:encoded></item><item><title><![CDATA[Build Your Own AI API With Google Gemini and Air Pipe]]></title><description><![CDATA[Artificial Intelligence is at the forefront of innovation, and with Google Gemini AI, developers can unlock advanced capabilities for their applications. However, creating a custom API to tap into Gemini’s full power can seem complex without the righ...]]></description><link>https://blog.airpipe.io/build-your-own-ai-api-with-google-gemini-and-air-pipe</link><guid isPermaLink="true">https://blog.airpipe.io/build-your-own-ai-api-with-google-gemini-and-air-pipe</guid><category><![CDATA[airpipe]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Rust]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Google]]></category><category><![CDATA[gemini]]></category><category><![CDATA[Devops]]></category><category><![CDATA[SRE]]></category><category><![CDATA[Databases]]></category><dc:creator><![CDATA[Kav Pather]]></dc:creator><pubDate>Sun, 29 Sep 2024 18:11:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727627628963/b9319187-da49-4943-8e7d-ff40410956b5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Artificial Intelligence is at the forefront of innovation, and with Google Gemini AI, developers can unlock advanced capabilities for their applications. However, creating a custom API to tap into Gemini’s full power can seem complex without the right tools.</p>
<p>That’s where <strong>Air Pipe</strong> comes in. Air Pipe is a fast, scalable, and secure API platform that simplifies the process of building, deploying, and managing APIs. In this guide, we’ll show you how to leverage Google Gemini AI’s API and Air Pipe to create your own AI-powered API in just a few easy steps.</p>
<p>Whether you're looking to automate tasks, enhance your app with AI, or streamline data processing, this tutorial will walk you through generating a Google Gemini API key and configuring a simple yet powerful API using Air Pipe. By the end, you'll have a fully functioning API ready to deploy—allowing you to integrate cutting-edge AI with ease.</p>
<p>Let’s dive in and build something amazing with Google Gemini and Air Pipe!</p>
<h2 id="heading-step-by-step-guide-to-build-your-own-ai-api"><strong>Step-by-Step Guide to Build Your Own AI API</strong></h2>
<p>This tutorial will focus on the cloud platform deployment but will also work seamlessly for self hosted deployments, you can learn how to self host here → <a target="_blank" href="https://docs.airpipe.io/docs/tutorial/setup"><strong>https://docs.airpipe.io/docs/tutorial/setup</strong></a> .</p>
<p><strong>Prerequisites:</strong></p>
<ul>
<li><p><a target="_blank" href="https://app.airpipe.io/register"><strong>Sign up</strong></a> or <a target="_blank" href="https://app.airpipe.io/login"><strong>log in</strong></a> to Air Pipe.</p>
</li>
<li><p>Google account and API Key</p>
</li>
</ul>
<h3 id="heading-step-0-get-your-google-gemini-api-key">Step 0: Get your Google Gemini API Key</h3>
<p>Navigate to <a target="_blank" href="https://aistudio.google.com/app/apikey">https://aistudio.google.com/app/apikey</a> and select “Create API Key”.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727628474539/59b1d8ee-3ca0-4c68-889d-727bcb05397d.png" alt class="image--center mx-auto" /></p>
<p>Create a new project if you have not already.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727628485553/d2a2427f-59f2-4e78-a256-b386b33026af.png" alt class="image--center mx-auto" /></p>
<blockquote>
<p>For production deployments we understand your API keys are sensitive, we provide encrypted variable (secret) support <a target="_blank" href="https://docs.airpipe.io/docs/configuration/managed-variables">https://docs.airpipe.io/docs/configuration/managed-variables</a> .</p>
<p>The examples below will utilize this system storing the key as <code>gemini-key</code> which is then accessed with <code>a|ap_var::gemini-key|</code> .</p>
<p>Other secret stores are also supported.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727628577601/00e683c6-1be6-4384-a799-aabd30898a99.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-1-create-your-configuration"><strong>Step 1: Create your Configuration</strong></h3>
<p>Once signed in to your Air Pipe account, head to <a target="_blank" href="https://app.airpipe.io/configurations"><strong>Configurations</strong></a> &gt; <strong>Add New</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726799364352/3b6c0377-1d6b-4b38-badb-f183ca6e6033.png?auto=compress,format&amp;format=webp" alt /></p>
<h3 id="heading-step-2-create-a-http-post-interface">Step 2: Create a HTTP POST interface</h3>
<p>In the YAML editor paste the below example. Here we simply define a HTTP POST interface and route called <strong>gemini/query</strong> . We further define our first <a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions">action</a> to check the body of the payload for a <strong>text</strong> attribute to exist and <a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions/asserts">assert</a> that it must be less than 20 characters (this is a simple example for illustrative purposes).</p>
<blockquote>
<p><a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions/asserts">Assertions</a> are important to understand as we can control what the user is allowed to input, and then we can further control the outcome of the API and action with the configured <a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions/asserts/functions">tests</a> .</p>
</blockquote>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">AskGemini</span>

<span class="hljs-attr">interfaces:</span>
  <span class="hljs-attr">gemini/query:</span> <span class="hljs-comment"># http route will be defaulted to this interface name</span>
    <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span>
    <span class="hljs-attr">input:</span> <span class="hljs-string">a|body</span>
    <span class="hljs-attr">output:</span> <span class="hljs-string">http</span>

    <span class="hljs-attr">actions:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">CheckBody</span>
        <span class="hljs-attr">input:</span> <span class="hljs-string">a|body</span> <span class="hljs-comment"># access the post body as the input to assert</span>
        <span class="hljs-attr">assert:</span>
          <span class="hljs-attr">tests:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">value:</span> <span class="hljs-string">text</span>
              <span class="hljs-attr">is_not_null:</span> <span class="hljs-literal">true</span>
              <span class="hljs-attr">is_less_than:</span> <span class="hljs-number">20</span> <span class="hljs-comment"># limit the amount of characters</span>
</code></pre>
<h3 id="heading-step-3-retrieving-the-full-gemini-response">Step 3: Retrieving the full Gemini Response</h3>
<p>Let’s extend the configuration and pass the <strong>text</strong> attribute to the Google Gemini API, we do this using <code>a|CheckBody::text|</code> in our configuration. We will also use <a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions/workflow-control">workflow control</a>, to ensure the <strong>CheckBody</strong> action succeeds before querying Google Gemini AI with <a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions/workflow-control/examples#when-succeeded"><code>run_when_succeeded</code></a>.</p>
<blockquote>
<p>We are using Action Variables to dynamically substitute the value into the payload, see our docs on <a target="_blank" href="https://docs.airpipe.io/docs/configuration/substitutions">variable substitutions</a> for further details and options.</p>
</blockquote>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Important! In the <strong>URL </strong>field below we are using <code>a|ap_var::gemini-key|</code> this implies we have a variable stored on the Air Pipe platform named <code>gemini-key</code> to access. See <a target="_blank" href="https://docs.airpipe.io/docs/configuration/managed-variables">Managed Variables</a> if you’d like to do the same. Otherwise update this with your key or use your own secret store or environment variable if self hosting.</div>
</div>

<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">AskGemini</span>

<span class="hljs-attr">interfaces:</span>
  <span class="hljs-attr">gemini/query:</span>
    <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span>
    <span class="hljs-attr">input:</span> <span class="hljs-string">a|body</span>
    <span class="hljs-attr">output:</span> <span class="hljs-string">http</span>

    <span class="hljs-attr">actions:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">CheckBody</span>
        <span class="hljs-attr">input:</span> <span class="hljs-string">a|body</span>
        <span class="hljs-attr">assert:</span>
          <span class="hljs-attr">tests:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">value:</span> <span class="hljs-string">text</span>
              <span class="hljs-attr">is_not_null:</span> <span class="hljs-literal">true</span>
              <span class="hljs-attr">is_less_than:</span> <span class="hljs-number">20</span> <span class="hljs-comment"># limit the amount of characters</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">QueryGemini</span>
        <span class="hljs-attr">run_when_succeeded:</span> [<span class="hljs-string">previous</span>] <span class="hljs-comment"># only run after CheckBody succeeds</span>
        <span class="hljs-attr">http:</span> 
          <span class="hljs-attr">url:</span> <span class="hljs-string">https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=a|ap_var::gemini-key|</span>
          <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span>
          <span class="hljs-attr">headers:</span>
            <span class="hljs-attr">content-type:</span> <span class="hljs-string">application/json</span>
          <span class="hljs-attr">body:</span> <span class="hljs-string">|</span> <span class="hljs-comment"># substitute the 'text' we just validated in 'CheckBody' into the body payload</span>
            {<span class="hljs-string">"contents"</span><span class="hljs-string">:</span>[{<span class="hljs-string">"parts"</span><span class="hljs-string">:</span>[{<span class="hljs-string">"text"</span><span class="hljs-string">:"a|CheckBody::text|"</span>}]}]}
</code></pre>
<h3 id="heading-step-4-deploy-and-test"><strong>Step 4: Deploy and Test</strong></h3>
<ul>
<li><p>Set your permission as <strong>USER_WITH_PUBLIC_READ</strong></p>
</li>
<li><p>Select <strong>Deploy to Staging</strong> and <strong>Deploy to Production</strong> and hit create.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726575183159/8e527604-8159-440b-8e2d-c9771487547d.png?auto=compress,format&amp;format=webp" alt /></p>
<p>Use your favorite API testing tool, or do a curl to your endpoints, let’s try the <code>gemini/query</code> route, make sure you update your organization uuid in the route.</p>
<p>You can find your <strong>organization uuid</strong> under <a target="_blank" href="https://app.airpipe.io/configurations"><strong>Configurations</strong></a> or in your <a target="_blank" href="https://app.airpipe.io/organization/settings"><strong>Organization Settings.</strong></a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726803296479/42dfb530-265e-4770-be9c-9a8d71813bb3.png?auto=compress,format&amp;format=webp" alt /></p>
<ul>
<li><p>Send a HTTP POST with a JSON payload eg. <code>{"text": "tell me about dogs"}</code> to <code>gemini/query</code> to retrieve the response.</p>
</li>
<li><p>Send a HTTP POST with a JSON payload eg. <code>{"text": "tell me about really big dogs"}</code> to test the length condition triggering a failure and preventing the <strong>QueryGemini</strong> action from proceeded.</p>
</li>
</ul>
<p><a target="_blank" href="https://api.airpipe.io/YOUR-ORGANIZATION-UUID/production/gemini/query"><strong>https://api.airpipe.io/YOUR-ORGANIZATION-UUID/production/gemini/query</strong></a></p>
<pre><code class="lang-json">curl --location 'https:<span class="hljs-comment">//api.airpipe.io/YOUR-ORGANIZATION-UUID/production/gemini/query' \</span>
--header 'Content-Type: application/json' \
--data '{
    <span class="hljs-attr">"text"</span>: <span class="hljs-string">"tell me about dogs"</span>
}'
</code></pre>
<p>Example response:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"data"</span>: {
        <span class="hljs-attr">"CheckBody"</span>: {
            <span class="hljs-attr">"time.ms"</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">"data"</span>: {
                <span class="hljs-attr">"text"</span>: <span class="hljs-string">"tell me about dogs"</span>
            },
            <span class="hljs-attr">"message"</span>: <span class="hljs-string">"success"</span>
        },
        <span class="hljs-attr">"QueryGemini"</span>: {
            <span class="hljs-attr">"time.ms"</span>: <span class="hljs-number">4180</span>,
            <span class="hljs-attr">"data"</span>: {
                <span class="hljs-attr">"status"</span>: <span class="hljs-number">200</span>,
                <span class="hljs-attr">"headers"</span>: {
                    <span class="hljs-attr">"content-type"</span>: <span class="hljs-string">"application/json; charset=UTF-8"</span>,
                    <span class="hljs-attr">"vary"</span>: <span class="hljs-string">"Origin,Accept-Encoding"</span>,
                    <span class="hljs-attr">"date"</span>: <span class="hljs-string">"Sun, 29 Sep 2024 15:40:42 GMT"</span>,
                    <span class="hljs-attr">"server"</span>: <span class="hljs-string">"scaffolding on HTTPServer2"</span>,
                    <span class="hljs-attr">"cache-control"</span>: <span class="hljs-string">"private"</span>,
                    <span class="hljs-attr">"x-xss-protection"</span>: <span class="hljs-string">"0"</span>,
                    <span class="hljs-attr">"x-frame-options"</span>: <span class="hljs-string">"SAMEORIGIN"</span>,
                    <span class="hljs-attr">"x-content-type-options"</span>: <span class="hljs-string">"nosniff"</span>,
                    <span class="hljs-attr">"server-timing"</span>: <span class="hljs-string">"gfet4t7; dur=4016"</span>,
                    <span class="hljs-attr">"alt-svc"</span>: <span class="hljs-string">"h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000"</span>,
                    <span class="hljs-attr">"accept-ranges"</span>: <span class="hljs-string">"none"</span>
                },
                <span class="hljs-attr">"body"</span>: {
                    <span class="hljs-attr">"candidates"</span>: [
                        {
                            <span class="hljs-attr">"content"</span>: {
                                <span class="hljs-attr">"parts"</span>: [
                                    {
                                        <span class="hljs-attr">"text"</span>: <span class="hljs-string">"## Dogs: Man's Best Friend, and More!\n\nDogs, those furry, wagging companions, have been by our side for thousands of years. They're more than just pets; they're loyal friends, helpful assistants, and sometimes even family members. Let's delve into what makes dogs so special:\n\n**Origins and History:**\n\n* **Wolf Ancestry:** Domestic dogs are descended from wolves, with the earliest evidence of domestication dating back 15,000 years.\n* **Evolution:** Over time, dogs evolved to work alongside humans in various roles like hunting, herding, and guarding. This led to the development of different breeds, each with unique physical and behavioral characteristics.\n\n**Breed Diversity:**\n\n* **Over 300 Breeds:** The world boasts a fascinating variety of dog breeds, each with a distinct appearance, temperament, and purpose.\n* **Classifications:** Breeds are categorized based on their size, coat type, and intended roles, like working, herding, sporting, and companion dogs. \n* **Unique Traits:** From tiny Chihuahuas to massive Great Danes, each breed has its own personality and quirks.\n\n**Personality and Behavior:**\n\n* **Social Creatures:** Dogs are highly social animals, forming strong bonds with their human families.\n* **Intelligence and Trainability:** Many dogs are incredibly intelligent and capable of learning complex commands and tricks. \n* **Emotionally Expressive:** Dogs communicate their emotions through body language, vocalizations, and facial expressions.\n* **Individual Differences:**  While certain breeds tend to have specific temperament traits, each dog is an individual with their own unique personality.\n\n**Health and Care:**\n\n* **Lifespan:** Depending on the breed, dogs can live anywhere from 10 to 20 years.\n* **Nutrition and Exercise:** Dogs require a balanced diet and regular exercise to stay healthy and happy.\n* **Grooming:** Different breeds have different grooming needs, ranging from occasional brushing to daily baths.\n* **Veterinary Care:** Regular checkups, vaccinations, and preventative measures are crucial for maintaining good health.\n\n**Beyond Companionship:**\n\n* **Working Dogs:** Dogs play vital roles in various professions, including law enforcement, search and rescue, assistance for individuals with disabilities, and therapy work.\n* **Emotional Support:** Dogs provide emotional support, reduce stress, and improve mental well-being.\n* **Family Members:** For many families, dogs become cherished members, offering unconditional love, companionship, and joy.\n\n**Getting a Dog:**\n\n* **Research:** Before getting a dog, consider your lifestyle, living situation, and the breed's temperament and care requirements.\n* **Adopting:** Consider adopting a dog from a shelter or rescue organization, giving a loving home to a dog in need.\n* **Responsible Ownership:** Be prepared to provide a dog with a safe, loving environment, proper care, and training.\n\nDogs enrich our lives in countless ways. They offer companionship, loyalty, and unconditional love, making them truly deserving of their title: \"Man's Best Friend.\" \n"</span>
                                    }
                                ],
                                <span class="hljs-attr">"role"</span>: <span class="hljs-string">"model"</span>
                            },
                            <span class="hljs-attr">"finishReason"</span>: <span class="hljs-string">"STOP"</span>,
                            <span class="hljs-attr">"index"</span>: <span class="hljs-number">0</span>,
                            <span class="hljs-attr">"safetyRatings"</span>: [
                                {
                                    <span class="hljs-attr">"category"</span>: <span class="hljs-string">"HARM_CATEGORY_SEXUALLY_EXPLICIT"</span>,
                                    <span class="hljs-attr">"probability"</span>: <span class="hljs-string">"NEGLIGIBLE"</span>
                                },
                                {
                                    <span class="hljs-attr">"category"</span>: <span class="hljs-string">"HARM_CATEGORY_HATE_SPEECH"</span>,
                                    <span class="hljs-attr">"probability"</span>: <span class="hljs-string">"NEGLIGIBLE"</span>
                                },
                                {
                                    <span class="hljs-attr">"category"</span>: <span class="hljs-string">"HARM_CATEGORY_HARASSMENT"</span>,
                                    <span class="hljs-attr">"probability"</span>: <span class="hljs-string">"NEGLIGIBLE"</span>
                                },
                                {
                                    <span class="hljs-attr">"category"</span>: <span class="hljs-string">"HARM_CATEGORY_DANGEROUS_CONTENT"</span>,
                                    <span class="hljs-attr">"probability"</span>: <span class="hljs-string">"NEGLIGIBLE"</span>
                                }
                            ]
                        }
                    ],
                    <span class="hljs-attr">"usageMetadata"</span>: {
                        <span class="hljs-attr">"promptTokenCount"</span>: <span class="hljs-number">4</span>,
                        <span class="hljs-attr">"candidatesTokenCount"</span>: <span class="hljs-number">642</span>,
                        <span class="hljs-attr">"totalTokenCount"</span>: <span class="hljs-number">646</span>
                    }
                }
            }
        }
    }
}
</code></pre>
<h3 id="heading-step-5-clean-up-the-gemini-response">Step 5: Clean up the Gemini Response</h3>
<p>As you can see with the response returned above, Google Gemini returns a lot of additional data you do not need to expose to your end users. We can use <a target="_blank" href="https://0feaf97f.dummy-ap.pages.dev/docs/configuration/interfaces/actions/transforms/functions"><code>post_transforms</code></a> with <a target="_blank" href="https://0feaf97f.dummy-ap.pages.dev/docs/configuration/interfaces/actions/transforms/functions#extract-value"><code>extract_value</code></a> to target the <code>text</code> attribute to return.</p>
<p>Go to <a target="_blank" href="https://app.airpipe.io/configurations">Configurations</a> and find your <strong>AskGemini</strong> configuration and click update, and paste the below.</p>
<blockquote>
<p>View <a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions/transforms/functions">Transforms &amp; Functions</a> for further ways to manipulate your data.</p>
</blockquote>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">AskGemini</span>

<span class="hljs-attr">interfaces:</span>
  <span class="hljs-attr">gemini/query:</span>
    <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span>
    <span class="hljs-attr">input:</span> <span class="hljs-string">a|body</span>
    <span class="hljs-attr">output:</span> <span class="hljs-string">http</span>

    <span class="hljs-attr">actions:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">CheckBody</span>
        <span class="hljs-attr">input:</span> <span class="hljs-string">a|body</span>
        <span class="hljs-attr">assert:</span>
          <span class="hljs-attr">tests:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">value:</span> <span class="hljs-string">text</span>
              <span class="hljs-attr">is_not_null:</span> <span class="hljs-literal">true</span>
              <span class="hljs-attr">is_less_than:</span> <span class="hljs-number">20</span> <span class="hljs-comment"># limit the amount of characters</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">QueryGemini</span>
        <span class="hljs-attr">run_when_succeeded:</span> [<span class="hljs-string">previous</span>] <span class="hljs-comment"># only run after CheckBody succeeds</span>
        <span class="hljs-attr">http:</span> 
          <span class="hljs-attr">url:</span> <span class="hljs-string">https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=a|ap_var::gemini-key|</span>
          <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span>
          <span class="hljs-attr">headers:</span>
            <span class="hljs-attr">content-type:</span> <span class="hljs-string">application/json</span>
          <span class="hljs-attr">body:</span> <span class="hljs-string">|</span> <span class="hljs-comment"># substitute the 'text' we just validated in 'CheckBody' into the body payload</span>
            {<span class="hljs-string">"contents"</span><span class="hljs-string">:</span>[{<span class="hljs-string">"parts"</span><span class="hljs-string">:</span>[{<span class="hljs-string">"text"</span><span class="hljs-string">:"a|CheckBody::text|"</span>}]}]} 
        <span class="hljs-attr">post_transforms:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">extract_value:</span> <span class="hljs-string">".body.candidates[0].content.parts[0].text"</span>
</code></pre>
<p>Example response:</p>
<pre><code class="lang-json">    {
        <span class="hljs-attr">"data"</span>: {
            <span class="hljs-attr">"CheckBody"</span>: {
                <span class="hljs-attr">"time.ms"</span>: <span class="hljs-number">0</span>,
                <span class="hljs-attr">"data"</span>: {
                    <span class="hljs-attr">"text"</span>: <span class="hljs-string">"tell me about dogs"</span>
                },
                <span class="hljs-attr">"message"</span>: <span class="hljs-string">"success"</span>
            },
            <span class="hljs-attr">"QueryGemini"</span>: {
                <span class="hljs-attr">"time.ms"</span>: <span class="hljs-number">4111</span>,
                <span class="hljs-attr">"data"</span>: <span class="hljs-string">"## Dogs: The Best Friends of Humans\n\nDogs, also known as **Canis lupus familiaris**, are domesticated mammals that have been companions to humans for thousands of years. Their loyalty, intelligence, and playful nature have made them beloved pets worldwide.\n\n**Here's a breakdown of some key aspects of dogs:**\n\n**Physical Characteristics:**\n\n* **Size:** Dogs come in a wide range of sizes, from tiny Chihuahuas to massive Great Danes.\n* **Coat:** Dog coats vary in length, texture, and color. Some have short, smooth coats, while others have long, fluffy fur.\n* **Tail:** Most dogs have tails that wag when they are happy. Tail length and shape can vary depending on the breed.\n* **Ears:** Dog ears come in various shapes and sizes, from floppy to erect.\n* **Snout:** Dogs have a strong sense of smell, which is aided by their long, pointed snouts.\n\n**Behavior:**\n\n* **Intelligence:** Dogs are highly intelligent animals, capable of learning complex commands and tasks.\n* **Socialization:** Dogs are social animals that thrive on interaction with humans and other dogs.\n* **Loyalty:** Dogs are known for their loyalty and devotion to their owners.\n* **Playfulness:** Dogs are playful animals that enjoy games and activities.\n* **Training:** Dogs are highly trainable, and with proper training, they can learn a wide range of behaviors.\n\n**Breeds:**\n\nThere are over 300 recognized dog breeds, each with its own unique physical characteristics and temperament. Some popular breeds include:\n\n* **Golden Retriever:** Friendly, intelligent, and eager to please.\n* **Labrador Retriever:** Loyal, playful, and known for their love of water.\n* **German Shepherd:** Intelligent, loyal, and protective.\n* **Poodle:** Intelligent, hypoallergenic, and known for their curly coats.\n* **French Bulldog:** Affectionate, playful, and known for their bat ears.\n\n**Health:**\n\n* **Lifespan:** The average lifespan of a dog is 10-13 years, but some breeds can live longer.\n* **Diet:** Dogs need a balanced diet that is rich in protein, carbohydrates, and essential nutrients.\n* **Exercise:** Most dogs need regular exercise to stay healthy and happy.\n* **Veterinary care:** Regular veterinary checkups and vaccinations are essential for maintaining a dog's health.\n\n**Benefits of Owning a Dog:**\n\n* **Companionship:** Dogs provide companionship and unconditional love.\n* **Stress relief:** Owning a dog can help reduce stress and anxiety.\n* **Exercise and activity:** Dogs encourage their owners to be more active.\n* **Improved mental health:** Studies have shown that owning a dog can improve mental health.\n* **Protection:** Some breeds are known for their protective instincts.\n\n**Conclusion:**\n\nDogs are wonderful companions that offer many benefits to their owners. Whether you're looking for a loyal friend, a playful companion, or a furry family member, there's a dog breed out there for everyone."</span>
            }
        }
    }
</code></pre>
<h3 id="heading-step-6-restricting-and-manipulating-the-text-prompt">Step 6: Restricting and manipulating the text prompt</h3>
<p>As you’ve seen before we can restrict the input text with certain conditions. However we may also want to restrict what we are requesting from Google Gemini AI, or want it to behave or respond in a particular way.</p>
<p>In our example lets say we want a maximum of 100 characters returned only.</p>
<p>We can simply modify the body we are sending to Google Gemini AI to prefix the <code>text</code> with some additional text eg. <code>Your response to the following question should be less than 100 characters: a|CheckBody::text|</code> .</p>
<pre><code class="lang-json"> {<span class="hljs-attr">"contents"</span>:[{<span class="hljs-attr">"parts"</span>:[{<span class="hljs-attr">"text"</span>:<span class="hljs-string">"Your response to the following question should be less than 100 characters: a|CheckBody::text|"</span>}]}]}
</code></pre>
<p>Complete example:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">AskGemini</span>

<span class="hljs-attr">interfaces:</span>
  <span class="hljs-attr">gemini/query:</span>
    <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span>
    <span class="hljs-attr">input:</span> <span class="hljs-string">a|body</span>
    <span class="hljs-attr">output:</span> <span class="hljs-string">http</span>

    <span class="hljs-attr">actions:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">CheckBody</span>
        <span class="hljs-attr">input:</span> <span class="hljs-string">a|body</span>
        <span class="hljs-attr">assert:</span>
          <span class="hljs-attr">tests:</span>
            <span class="hljs-bullet">-</span> <span class="hljs-attr">value:</span> <span class="hljs-string">text</span>
              <span class="hljs-attr">is_not_null:</span> <span class="hljs-literal">true</span>
              <span class="hljs-attr">is_less_than:</span> <span class="hljs-number">20</span> <span class="hljs-comment"># limit the amount of input characters</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">QueryGemini</span>
        <span class="hljs-attr">run_when_succeeded:</span> [<span class="hljs-string">previous</span>] <span class="hljs-comment"># only run after CheckBody succeeds</span>
        <span class="hljs-attr">http:</span> <span class="hljs-comment"># store your gemini key in the hosted variables or substitute a|ap_var::gemini-key| with your key if testing # https://aistudio.google.com/app/apikey</span>
          <span class="hljs-attr">url:</span> <span class="hljs-string">https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=a|ap_var::gemini-key|</span>
          <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span>
          <span class="hljs-attr">headers:</span>
            <span class="hljs-attr">content-type:</span> <span class="hljs-string">application/json</span>
          <span class="hljs-attr">body:</span> <span class="hljs-string">|</span> <span class="hljs-comment"># substitute the 'text' we just validated in 'CheckBody' into the body payload</span>
            {<span class="hljs-string">"contents"</span><span class="hljs-string">:</span>[{<span class="hljs-string">"parts"</span><span class="hljs-string">:</span>[{<span class="hljs-string">"text"</span><span class="hljs-string">:"Your</span> <span class="hljs-attr">response to the following question should be less than 100 characters:</span> <span class="hljs-string">a|CheckBody::text|"</span>}]}]} 
        <span class="hljs-attr">post_transforms:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-attr">extract_value:</span> <span class="hljs-string">".body.candidates[0].content.parts[0].text"</span>
</code></pre>
<p>Example response:</p>
<pre><code class="lang-json">    {
        <span class="hljs-attr">"data"</span>: {
            <span class="hljs-attr">"CheckBody"</span>: {
                <span class="hljs-attr">"time.ms"</span>: <span class="hljs-number">0</span>,
                <span class="hljs-attr">"data"</span>: {
                    <span class="hljs-attr">"text"</span>: <span class="hljs-string">"tell me about dogs"</span>
                },
                <span class="hljs-attr">"message"</span>: <span class="hljs-string">"success"</span>
            },
            <span class="hljs-attr">"QueryGemini"</span>: {
                <span class="hljs-attr">"time.ms"</span>: <span class="hljs-number">1907</span>,
                <span class="hljs-attr">"data"</span>: <span class="hljs-string">"Dogs are loyal, furry companions known for their intelligence and love. 🐶 \n"</span>
            }
        }
    }
</code></pre>
<p>Now you finally have a nice clean response from Google Gemini AI for your end users to consume. We have securely stored the API key, validated the input text, cleaned the data and effectively sandboxed the output response.</p>
<h3 id="heading-so-with-that-youre-done-whats-next"><strong>So with that you’re done! Whats Next?</strong></h3>
<p>Air Pipe provides you a fast, consistent and robust development experience that you can continue extending with confidence across anything you build.</p>
<p>You can further extend your configuration to connect to <a target="_blank" href="https://docs.airpipe.io/docs/tutorial/database-to-api">databases</a> and other endpoints all in the one configuration with workflow controls at your disposal.</p>
<p>See:</p>
<ul>
<li><p><a target="_blank" href="https://docs.airpipe.io/docs/tutorial/database-to-api">Databases</a></p>
</li>
<li><p><a target="_blank" href="https://docs.airpipe.io/docs/tutorial/setup">Tutorial</a></p>
</li>
<li><p><a target="_blank" href="https://docs.airpipe.io/docs/configuration">Configuration</a></p>
</li>
<li><p><a target="_blank" href="https://docs.airpipe.io/docs/tutorial/validating-data"><strong>Validating Data</strong></a></p>
</li>
</ul>
<h3 id="heading-performance-and-reliability-built-on-rust">Performance and Reliability Built on Rust</h3>
<p>One of the core strengths of Air Pipe is that it is built on <strong>Rust</strong>, known for its <strong>memory safety</strong>, <strong>thread safety</strong>, and <strong>high performance</strong>. Whether you're managing large-scale databases or smaller applications, Rust ensures your APIs run smoothly and securely.</p>
<h3 id="heading-why-google-gemini">Why Google Gemini?</h3>
<p>Google Gemini AI is a powerful platform for advanced natural language processing and machine learning, ideal for building intelligent, scalable applications. Its real-time capabilities and seamless integration make it a top choice for AI-driven services.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>integrating Google Gemini AI with Air Pipe allows developers to build powerful, scalable APIs with ease. By combining Gemini's advanced AI capabilities with Air Pipe's speed, security, and simple deployment, you can create intelligent applications that handle complex tasks efficiently.</p>
<p>Whether you're automating workflows or enhancing data analysis, this seamless integration empowers you to innovate faster. Start building your API today and unlock new possibilities with Air Pipe and Google Gemini AI.</p>
<p>Ready to get started? Head over to <a target="_blank" href="https://airpipe.io/"><strong>Air Pipe</strong></a> and build your first Gemini API in minutes.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Visit <a target="_blank" href="https://airpipe.io/"><strong>Air Pipe</strong></a></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Find us on <a target="_blank" href="https://discord.com/invite/b8mFtjWXZj"><strong>Discord</strong></a></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><a target="_blank" href="https://docs.airpipe.io/docs/examples/Google/gemini-ai">Google Gemini AI Examples</a></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><a target="_blank" href="https://ai.google.dev/api/all-methods">https://ai.google.dev/api/all-methods</a></div>
</div>]]></content:encoded></item><item><title><![CDATA[Build MongoDB APIs in 30 Seconds]]></title><description><![CDATA[Are you tired of spending countless hours configuring your APIs and managing complex workflows for your MongoDB database? What if we told you that you could set up a fully functional API in just 30 seconds? In this article, we’ll show you how Air Pip...]]></description><link>https://blog.airpipe.io/build-mongodb-apis-in-30-seconds</link><guid isPermaLink="true">https://blog.airpipe.io/build-mongodb-apis-in-30-seconds</guid><category><![CDATA[airpipe]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Rust]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Databases]]></category><category><![CDATA[NoSQL]]></category><category><![CDATA[Devops]]></category><category><![CDATA[SRE]]></category><dc:creator><![CDATA[Kav Pather]]></dc:creator><pubDate>Fri, 20 Sep 2024 04:15:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1726574917252/f94e10c1-5452-4118-82b9-a7fe8fdc35df.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you tired of spending countless hours configuring your APIs and managing complex workflows for your MongoDB database? What if we told you that you could set up a fully functional API in just 30 seconds? In this article, we’ll show you how Air Pipe’s <strong>cutting-edge platform</strong> makes API creation fast, efficient, and hassle-free.</p>
<h3 id="heading-why-air-pipe">Why Air Pipe?</h3>
<p>Air Pipe revolutionizes API development, offering a platform where building, deploying, and managing APIs, integrations and workflows takes mere seconds.</p>
<p>Here's why Air Pipe is a game changer:</p>
<ul>
<li><p><strong>Instant Deployment</strong>: Get your MongoDB APIs running in 30 seconds flat.</p>
</li>
<li><p><strong>Secure &amp; Scalable</strong>: Built on Rust for memory and thread safety, ensuring your APIs are secure, fast, and scalable.</p>
</li>
<li><p><strong>Flexible Integration</strong>: Effortlessly integrate with databases like MongoDB and more, connect to HTTP endpoints, and run scripts or commands.</p>
</li>
<li><p><strong>Deploy Anywhere</strong>: Use Air Pipe's cloud platform or deploy it self-hosted on any infrastructure.</p>
</li>
</ul>
<h3 id="heading-step-by-step-guide-to-building-mongodb-apis">Step-by-Step Guide to Building MongoDB APIs</h3>
<p>This tutorial will focus on the cloud platform deployment but will also work seamlessly for self hosted deployments, you can learn how to self host here → <a target="_blank" href="https://docs.airpipe.io/docs/tutorial/setup">https://docs.airpipe.io/docs/tutorial/setup</a> .</p>
<p><strong>Prerequisites:</strong></p>
<ul>
<li><p><a target="_blank" href="https://app.airpipe.io/register">Sign up</a> or <a target="_blank" href="https://app.airpipe.io/login">log in</a> to Air Pipe.</p>
</li>
<li><p>MongoDB database or if you don’t have a MongoDB instance <a target="_blank" href="https://www.mongodb.com/cloud/atlas/register">register for MongoDB Atlas</a>, create a free cluster and load the sample dataset.</p>
<blockquote>
<p>We’ll be using the MongoDB sample dataset in this tutorial.</p>
</blockquote>
</li>
</ul>
<h4 id="heading-step-1-create-your-configuration"><strong>Step 1: Create your Configuration</strong></h4>
<p>Once signed in to your Air Pipe account, head to <strong>Configurations</strong> &gt; <strong>Add New</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726799364352/3b6c0377-1d6b-4b38-badb-f183ca6e6033.png" alt class="image--center mx-auto" /></p>
<p><strong>Step 2: Define your MongoDB Data Source</strong></p>
<p>Defining your data source is as simple as naming your <strong>database</strong>, setting a <strong>driver</strong> and adding a <strong>connection string</strong>.</p>
<blockquote>
<p>For production deployments we understand your connection string is sensitive, we provide encrypted variable (secret) support <a target="_blank" href="https://docs.airpipe.io/docs/configuration/managed-variables">https://docs.airpipe.io/docs/configuration/managed-variables</a> .</p>
<p>Other secret stores are also supported.</p>
</blockquote>
<p>In the YAML editor paste the below example and update the connection string.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">mongodb-find-example</span>
<span class="hljs-attr">description:</span> <span class="hljs-string">my</span> <span class="hljs-string">mongo</span> <span class="hljs-string">api</span>

<span class="hljs-attr">global:</span>
  <span class="hljs-attr">databases:</span>
    <span class="hljs-attr">main:</span> 
      <span class="hljs-attr">driver:</span> <span class="hljs-string">mongodb</span>
      <span class="hljs-attr">conn_string:</span> <span class="hljs-string">|</span>
        <span class="hljs-string">mongodb+srv://someUser:somePass@bob-perf.hello.mongodb.net/?retryWrites=true&amp;w=majority&amp;appName=my-test</span>
</code></pre>
<blockquote>
<p>The <strong>global</strong> block defines the databases, variables, secrets and templates to be used across API interfaces and its subsequent actions.</p>
</blockquote>
<h4 id="heading-step-3-creating-http-interfaces">Step 3: Creating HTTP interfaces</h4>
<p>It’s trivial to create a HTTP interface with Air Pipe, below we set a route name as <strong>mongodb/find</strong>, the method as <strong>POST</strong> and output to <strong>http</strong>.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">mongodb-find-example</span>
<span class="hljs-attr">description:</span> <span class="hljs-string">my</span> <span class="hljs-string">mongo</span> <span class="hljs-string">api</span>

<span class="hljs-attr">global:</span>
  <span class="hljs-attr">databases:</span>
    <span class="hljs-attr">main:</span> 
      <span class="hljs-attr">driver:</span> <span class="hljs-string">mongodb</span>
      <span class="hljs-attr">conn_string:</span> <span class="hljs-string">|
        mongodb+srv://someUser:somePass@bob-perf.hello.mongodb.net/?retryWrites=true&amp;w=majority&amp;appName=my-test
</span>
<span class="hljs-attr">interfaces:</span>
  <span class="hljs-attr">mongodb/find:</span> <span class="hljs-comment"># this will be used as our route name</span>
    <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span> <span class="hljs-comment"># method set to POST so we can accept input data</span>
    <span class="hljs-attr">output:</span> <span class="hljs-string">http</span> <span class="hljs-comment"># output set to HTTP</span>
</code></pre>
<blockquote>
<p>The same concept can be used for creating webhooks and creating an entry point to any of your configurations that access databases, commands, scripts and other HTTP endpoints.</p>
</blockquote>
<p><strong>Step 4: Define your Actions</strong></p>
<p><a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions"><strong>Actions</strong></a> are a set of instructions an interface will run when called.</p>
<ol>
<li><p>Select your <a target="_blank" href="https://docs.airpipe.io/docs/tutorial/nosql-database-to-api-connecting">database</a> to connect to i.e. <code>main</code></p>
</li>
<li><p>Set the <a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions/inputs/databases#document_operation">document operation</a> and filter.</p>
</li>
</ol>
<p>We’ll also add a <strong>mongodb/update</strong> interface while we’re at it.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">mongodb-operations</span>
<span class="hljs-attr">description:</span> <span class="hljs-string">use</span> <span class="hljs-string">any</span> <span class="hljs-string">mongodb</span> <span class="hljs-string">operation</span>

<span class="hljs-attr">global:</span>
  <span class="hljs-attr">databases:</span>
    <span class="hljs-attr">main:</span> 
      <span class="hljs-attr">driver:</span> <span class="hljs-string">mongodb</span>
      <span class="hljs-attr">conn_string:</span> <span class="hljs-string">|
        mongodb+srv://someUser:somePass@bob-perf.hello.mongodb.net/?retryWrites=true&amp;w=majority&amp;appName=Cluster0
</span>
<span class="hljs-attr">interfaces:</span>
  <span class="hljs-attr">mongodb/find:</span>
    <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span>
    <span class="hljs-attr">output:</span> <span class="hljs-string">http</span>

    <span class="hljs-attr">actions:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">MongoQuery</span>
        <span class="hljs-attr">database:</span> <span class="hljs-string">main</span>
        <span class="hljs-attr">document_operation:</span>
          <span class="hljs-attr">database:</span> <span class="hljs-string">sample_analytics</span> 
          <span class="hljs-attr">collection:</span> <span class="hljs-string">customers</span>
          <span class="hljs-attr">operation:</span> <span class="hljs-string">findOne</span>
          <span class="hljs-attr">filter:</span> <span class="hljs-string">'{"name": "a|body::name|"}'</span>

  <span class="hljs-attr">mongodb/update:</span>
    <span class="hljs-attr">method:</span> <span class="hljs-string">POST</span>
    <span class="hljs-attr">output:</span> <span class="hljs-string">http</span>

    <span class="hljs-attr">actions:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">MongoQuery</span>
        <span class="hljs-attr">database:</span> <span class="hljs-string">main</span>
        <span class="hljs-attr">document_operation:</span>
          <span class="hljs-attr">database:</span> <span class="hljs-string">sample_analytics</span>
          <span class="hljs-attr">collection:</span> <span class="hljs-string">customers</span>
          <span class="hljs-attr">operation:</span> <span class="hljs-string">updateOne</span>
          <span class="hljs-attr">filter:</span> <span class="hljs-string">'{"name": "a|body::name|"}'</span>
          <span class="hljs-attr">update:</span> <span class="hljs-string">'{"$set": {"active": a|body::status|}}'</span>
</code></pre>
<blockquote>
<p>For all available operations and settings view <a target="_blank" href="https://docs.airpipe.io/docs/configuration/interfaces/actions/inputs/databases#document_operation">https://docs.airpipe.io/docs/configuration/interfaces/actions/inputs/databases#document_operation</a></p>
</blockquote>
<h4 id="heading-step-5-deploy-and-test">Step 5: Deploy and Test</h4>
<ul>
<li><p>Set your permission as <strong>USER_WITH_PUBLIC_READ</strong></p>
</li>
<li><p>Select <strong>Deploy to Staging</strong> and <strong>Deploy to Production</strong> and hit create.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726575183159/8e527604-8159-440b-8e2d-c9771487547d.png" alt class="image--center mx-auto" /></p>
<p>It’s that easy your API is live and ready to be consumed in seconds.</p>
<p>Use your favorite API testing tool, or do a curl to your endpoints, let’s try the <code>mongodb/find</code> route, make sure you update your organization uuid in the route.</p>
<p>You can find your <strong>organization uuid</strong> under <a target="_blank" href="https://app.airpipe.io/configurations">Configurations</a> or in your <a target="_blank" href="https://app.airpipe.io/organization/settings">Organization Settings.</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1726803296479/42dfb530-265e-4770-be9c-9a8d71813bb3.png" alt class="image--center mx-auto" /></p>
<ul>
<li><p>Send a HTTP POST with a JSON payload eg. <code>{"name": "Elizabeth Ray"}</code> to <code>mongodb/find</code> to find a document with a matching name.</p>
</li>
<li><p>Send a HTTP POST with a JSON payload eg. <code>{"name": "Elizabeth Ray", "status": false}</code> to <code>mongodb/update</code> to find a document with a matching name and update the status value accordingly.</p>
</li>
</ul>
<p><a target="_blank" href="https://api.airpipe.io/f9fc628a-your-organization-UUID-ee4961020ad3/production/mongodb/find">https://api.airpipe.io/YOUR-ORGANIZATION-UUID/production/mongodb/find</a></p>
<pre><code class="lang-bash">curl --location <span class="hljs-string">'https://api.airpipe.io/YOUR-ORGANIZATION-UUID/production/mongodb/find'</span> \
--header <span class="hljs-string">'Content-Type: application/json'</span> \
--data <span class="hljs-string">'{
    "name": "Elizabeth Ray",
    "status": true
}'</span>
</code></pre>
<p>Example response:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"data"</span>: {
        <span class="hljs-attr">"MongoQuery"</span>: {
            <span class="hljs-attr">"time.ms"</span>: <span class="hljs-number">3</span>,
            <span class="hljs-attr">"data"</span>: {
                <span class="hljs-attr">"_id"</span>: {
                    <span class="hljs-attr">"$oid"</span>: <span class="hljs-string">"5ca4bbcea2dd94ee58162a68"</span>
                },
                <span class="hljs-attr">"username"</span>: <span class="hljs-string">"fmiller"</span>,
                <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Elizabeth Ray"</span>,
                <span class="hljs-attr">"address"</span>: <span class="hljs-string">"9286 Bethany Glens\nVasqueztown, CO 22939"</span>,
                <span class="hljs-attr">"birthdate"</span>: {
                    <span class="hljs-attr">"$date"</span>: {
                        <span class="hljs-attr">"$numberLong"</span>: <span class="hljs-string">"226117231000"</span>
                    }
                },
                <span class="hljs-attr">"email"</span>: <span class="hljs-string">"arroyocolton@gmail.com"</span>,
                <span class="hljs-attr">"active"</span>: <span class="hljs-literal">true</span>,
                <span class="hljs-attr">"accounts"</span>: [
                    <span class="hljs-number">371138</span>,
                    <span class="hljs-number">324287</span>,
                    <span class="hljs-number">276528</span>,
                    <span class="hljs-number">332179</span>,
                    <span class="hljs-number">422649</span>,
                    <span class="hljs-number">387979</span>
                ],
                <span class="hljs-attr">"tier_and_details"</span>: {
                    <span class="hljs-attr">"0df078f33aa74a2e9696e0520c1a828a"</span>: {
                        <span class="hljs-attr">"tier"</span>: <span class="hljs-string">"Bronze"</span>,
                        <span class="hljs-attr">"id"</span>: <span class="hljs-string">"0df078f33aa74a2e9696e0520c1a828a"</span>,
                        <span class="hljs-attr">"active"</span>: <span class="hljs-literal">true</span>,
                        <span class="hljs-attr">"benefits"</span>: [
                            <span class="hljs-string">"sports tickets"</span>
                        ]
                    },
                    <span class="hljs-attr">"699456451cc24f028d2aa99d7534c219"</span>: {
                        <span class="hljs-attr">"tier"</span>: <span class="hljs-string">"Bronze"</span>,
                        <span class="hljs-attr">"benefits"</span>: [
                            <span class="hljs-string">"24 hour dedicated line"</span>,
                            <span class="hljs-string">"concierge services"</span>
                        ],
                        <span class="hljs-attr">"active"</span>: <span class="hljs-literal">true</span>,
                        <span class="hljs-attr">"id"</span>: <span class="hljs-string">"699456451cc24f028d2aa99d7534c219"</span>
                    }
                }
            }
        }
    }
}
</code></pre>
<h3 id="heading-youre-done-whats-next">You’re done! Whats Next?</h3>
<p>Air Pipe provides you a fast, consistent and robust development experience that you can continue extending with confidence across anything you build.</p>
<p>You can further add testing, and schema validation for your payloads to suit your requirements or fetch additional data if required.</p>
<p>See:</p>
<ul>
<li><p><a target="_blank" href="https://docs.airpipe.io/docs/tutorial/validating-data">Validating Data</a></p>
</li>
<li><p><a target="_blank" href="https://docs.airpipe.io/docs/examples/mongodb/#mongodb-find-example">MongoDB Examples</a></p>
</li>
<li><p><a target="_blank" href="https://docs.airpipe.io/docs/tutorial/nosql-database-to-api">NoSQL Tutorial</a></p>
</li>
</ul>
<h3 id="heading-performance-and-reliability-built-on-rust">Performance and Reliability Built on Rust</h3>
<p>One of the core strengths of Air Pipe is that it is built on <strong>Rust</strong>, known for its <strong>memory safety</strong>, <strong>thread safety</strong>, and <strong>high performance</strong>. Whether you're managing large-scale databases or smaller applications, Rust ensures your APIs run smoothly and securely.</p>
<h3 id="heading-why-mongodb">Why MongoDB?</h3>
<p>MongoDB is a popular choice for developers due to its flexibility, scalability, and ease of use. Whether you're building a startup or an enterprise-grade application, MongoDB allows you to store and retrieve your data seamlessly. Coupled with Air Pipe's rapid deployment capabilities, it becomes easier than ever to launch and manage data-driven applications.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Building MongoDB APIs doesn't have to be a daunting task. With Air Pipe, you can achieve in 30 seconds what traditionally takes hours or even days. The combination of performance, security, and flexibility makes Air Pipe an ideal solution for developers and businesses seeking to streamline their workflows and get to market faster.</p>
<p>Ready to get started? Head over to <a target="_blank" href="https://airpipe.io/">Air Pipe</a> and build your first MongoDB API in just 30 seconds!</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Visit <a target="_blank" href="https://airpipe.io">Air Pipe</a></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Find us on <a target="_blank" href="https://discord.com/invite/b8mFtjWXZj">Discord</a></div>
</div>

<hr />
]]></content:encoded></item></channel></rss>