In the world of business automation, complexity is the enemy. As systems grow, simple scripts evolve into tangled webs of dependencies, making them fragile, difficult to debug, and impossible to scale. We need a better way to build—a method that prizes clarity, reliability, and reusability. Enter the concept of the atomic action, the fundamental building block of modern agentic workflows.
On the .do platform, an action.do is more than just a piece of code; it's the foundation of reliable Business-as-Code. It’s a self-contained, observable, and composable unit that performs a single, specific task. This is the new paradigm for building robust business automation.
The philosophy is simple: Define. Execute. Repeat.
Think of an "atomic action" in the same way you think of an atomic database transaction: it's the smallest, indivisible unit of work that must either succeed completely or fail cleanly. There is no partial success.
An action.do encapsulates this principle. It is a self-contained, reusable function designed to perform one specific task and do it well.
This atomicity is the key to building reliable systems. When a workflow fails, you don't have to untangle a monolithic script; you can pinpoint exactly which atomic workflow step failed and why. Debugging becomes simpler, and your system becomes inherently more resilient.
Defining an action on the .do platform transforms a simple function into a managed, reusable, and observable asset. Let's look at how you can define an action to enrich user data using a third-party service.
import { Do } from '@do-platform/sdk';
// Initialize the .do client with your API key
const-do = new Do(process.env.DO_API_KEY);
// Define a new atomic action to enrich user data
const enrichUserAction = await-do.action.create({
name: 'enrich-user-profile',
description: 'Fetches user data from Clearbit and updates the DB.',
inputs: {
email: 'string',
},
handler: async (inputs) => {
const userData = await clearbit.lookup(inputs.email);
const dbResult = await db.users.update({ email: inputs.email, data: userData });
return { success: true, userId: dbResult.id };
}
});
console.log('Action created:', enrichUserAction.id);
Let's break this down:
While an action.do might look similar to a serverless function (like AWS Lambda or Google Cloud Functions), it operates at a higher level of abstraction, designed specifically for building Services-as-Software.
A serverless function gives you a runtime environment. An action.do gives you a fully managed business capability. This includes:
A common question is, "Can an action call another action?"
The answer is no, and this is a core design principle for building scalable systems. Actions are atomic; they perform a single task. To create a sequence of tasks, you use a workflow.
This separation of concerns is critical. It prevents the creation of "spaghetti" automations where actions have hidden dependencies on each other. Your agentic workflow becomes a clear, readable process, and your actions remain independent, reusable, and easy to test.
By thinking in atomic units, you can build complex business logic from simple, reliable parts. Start defining your business, one action.do at a time.