Business logic has a tendency to get messy. What starts as a simple script to process an order eventually grows into a complex, tangled web of code. It becomes a monolith—brittle, difficult to update, and a nightmare to debug. When a single part fails, the entire system can grind to a halt. In today's fast-paced, AI-driven world, this model is no longer sustainable.
We need a new paradigm. A shift from monolithic processes to composable, resilient systems. This is where the concept of the atomic action comes in.
Imagine breaking down your most complex business processes into their smallest, most fundamental parts. A single function to send an email. A single function to update a CRM record. A single function to process a payment. Each part is self-contained, reliable, and does one thing flawlessly.
This is the philosophy behind action.do: Encapsulate Logic. Execute Flawlessly. It's about transforming any piece of business logic into a reliable, scalable, and observable atomic action—the fundamental building block for modern automation and AI-powered agentic workflows.
For years, automation has been built on scripts and services that grow over time. This organic growth leads to several key pain points:
This is where we redefine automation as Business As Code—treating business logic with the same discipline, modularity, and best practices as modern software development.
An atomic action on the .do platform is more than just a function; it's a structured, single-purpose microservice with a clearly defined contract. It's designed for maximum reliability and reusability.
Let's look at a simple action.do for processing a payment.
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_...' }
Let's break this down:
While an action.do might look like a standard serverless function, it's purpose-built for creating agentic workflows. A serverless function is general-purpose compute; an atomic action is a first-class business citizen.
The key difference lies in the surrounding ecosystem. The .do platform provides native state management, deep observability, and a framework for composition. Actions are designed from the ground up to be discoverable and executable by other services, humans, or AI agents, turning your business capabilities into a true toolbox.
The power of atomic actions is truly unlocked when you compose them. An individual action is intentionally limited to a single task. To orchestrate a sequence of tasks, you use a workflow.do.
This enforces a clean separation of concerns:
For example, a "New Customer Onboarding" workflow could chain together several atomic actions:
Each step is an independent, reusable, and robust action. If the notify-sales-on-slack action fails, it doesn't impact the process-subscription-payment action. You can update, debug, or scale each action individually.
This modularity is the key to building sophisticated agentic workflows, where an AI agent can be given a goal and a set of trusted tools (your atomic actions) to accomplish it. The AI doesn't need to know how to process a payment; it just needs to know that a reliable process-payment action exists and how to call it.
By moving from monolithic scripts to a collection of composable micro-actions, you gain immense benefits:
The future of business automation isn't about writing bigger scripts. It's about building smaller, smarter, and more composable pieces. It's time to break down the monolith and build the future with atomic actions.
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.