In software development, complexity is the enemy of reliability. As applications grow, scripts become entangled, and logic becomes monolithic, making systems brittle, hard to debug, and nearly impossible to scale. We've all seen it: a simple change in one part of the code causes an unexpected failure in a completely different area.
But what if we took a lesson from a decades-old philosophy? The Unix philosophy preaches a simple, powerful idea: "Do one thing and do it well." This principle of creating small, single-purpose tools that can be chained together has proven incredibly robust.
Today, as we enter the era of agentic workflows and AI-driven business automation, this principle is more relevant than ever. Welcome to the world of atomic actions.
At its core, an atomic action is a self-contained, single-purpose function that performs one specific task reliably. Think of it as the ultimate LEGO brick for your business logic. Instead of a messy script that tries to do everything, you define discrete actions like:
On the action.do platform, we elevate this concept to a new level. We allow you to transform any piece of business logic into a reliable, scalable, and observable API endpoint. This is Business As Code: treating your core operational logic as a first-class citizen—modular, versioned, and testable.
You might be thinking, "Isn't this just another name for serverless functions or microservices?" While the underlying technology is similar, an action.do is purpose-built for the demands of modern automation and agentic systems.
Unlike a generic serverless function, an action.do is an opinionated building block with batteries included:
Let's see how this works in practice. Here's how you'd define a payment processing action using the .do SDK:
import { Do } from '@do-sdk/core';
// Define an atomic action to process a payment
const processPayment = Do.action('process-payment', {
inputs: {
customerId: 'string',
amount: 'number',
},
handler: async ({ inputs, context }) => {
// Connect to a payment provider like Stripe
console.log(`Processing payment of $${inputs.amount} for ${inputs.customerId}`);
// ... payment gateway logic here
// Return a structured result
return { success: true, transactionId: `txn_${context.runId}` };
},
});
// Execute the action securely via the .do API
const result = await processPayment.run({
customerId: 'cust_12345',
amount: 49.99,
});
console.log(result);
// Output: { success: true, transactionId: 'txn_...' }
Notice the clarity. The process-payment action has one job. It declares exactly what it needs (customerId, amount) and guarantees a structured response. This simple, powerful pattern makes your logic incredibly robust, reusable, and easy to test.
Here's where atomic actions become truly transformative. For an AI agent to reliably automate complex tasks, it needs a toolkit of dependable functions it can call upon.
An AI doesn't need to know the intricate details of your payment gateway's API. It just needs to know that a process-payment tool exists and that it requires a customerId and an amount.
Atomic actions provide this perfect level of abstraction. They serve as the stable, well-defined tools in an AI agent's toolbelt, allowing the agent to focus on decision-making and orchestration. By composing these actions within a workflow.do, you can build sophisticated, intelligent automations that are both powerful and maintainable.
By embracing the power of one, we build systems that are not only more reliable and scalable today but are also ready for the future of AI-powered automation.
What is an 'atomic action' on the .do platform?
An atomic action is a self-contained, single-purpose function that performs one specific task, like sending an email or updating a database record. It's the fundamental building block for creating reliable and modular agentic workflows.
How is an action.do different from a standard serverless function?
While similar, an action.do is purpose-built for agentic systems. It includes native integration with the .do ecosystem for state management, observability, and composition, allowing you to treat business logic as a first-class citizen in your Services-as-Software.
Can actions call other actions?
A single action is designed to be atomic and perform one task. To orchestrate multiple actions, you use a 'workflow.do', which composes individual actions into a larger, stateful process. This promotes a clean separation of concerns.
What kind of logic can I run inside an action.do?
Anything you can code. Actions can perform data transformations, integrate with third-party APIs (e.g., Stripe, SendGrid), query databases, or run machine learning models. It encapsulates any unit of business logic and exposes it as a simple API.
How are inputs and secrets handled in an action?
Inputs are defined with clear types in the action's configuration and are passed during execution. Secrets, like API keys or database credentials, are managed securely through the .do platform and injected into the action's context at runtime, never exposed in your code.