In the world of software development and operations, complexity is the enemy of progress. As our systems grow, so do the tangled webs of scripts, API calls, and manual processes that hold them together. These brittle, monolithic automations are difficult to debug, impossible to reuse, and a nightmare to maintain. What if we could break down these complex processes into simple, manageable, and powerful building blocks?
This is the core philosophy behind action.do: moving from tangled scripts to orchestrated agentic workflows built on a foundation of atomic actions. It's time to embrace a new paradigm of Business-as-Code.
An atomic action is the smallest, indivisible unit of work in a workflow. Think of it as a supercharged function designed to perform a single, specific task reliably and repeatably.
On the .do platform, an Action encapsulates a single piece of business logic. It's:
By focusing on these small, atomic units, you create a library of reliable capabilities that can be composed into something far greater.
Theory is great, but code makes it real. Let's see how simple it is to define a new Action using the .do TypeScript SDK. Here, we'll create an action to send a welcome email to a new user.
import { Action } from '@do-sdk/core';
// Define a new Action to send a welcome email
const sendWelcomeEmail = new Action({
name: 'send-welcome-email',
description: 'Sends a standardized welcome email to a new user.',
handler: async (inputs: { email: string; name: string }) => {
console.log(`Preparing to send email to ${inputs.email}...`);
// Logic to connect to an email service (e.g., SendGrid, SES)
// const emailSent = await emailService.send({
// to: inputs.email,
// subject: `Welcome, ${inputs.name}!`,
// body: 'We are so glad you joined us...'
// });
const result = { success: true, messageId: `msg_${Date.now()}` };
console.log('Email sent successfully:', result.messageId);
return result;
},
});
// Execute the action via the .do SDK
async function run() {
const execution = await sendWelcomeEmail.run({
email: 'alex@example.com',
name: 'Alex',
});
console.log('Execution Result:', execution);
}
run();
In this example, we define an Action with a unique name, a clear description, and a handler function that contains the core logic. The platform takes care of the rest, making it executable and discoverable.
"But wait," you might ask, "how is this different from a traditional serverless function?"
Actions on .do are functions on steroids, specifically designed for workflow orchestration. When you define an Action, it's automatically instrumented with:
This isn't just about running code; it's about turning your business logic into managed, composable assets.
While an Action is atomic, your business processes are not. The real power emerges when you chain Actions together in a Workflow. An Action should not call another Action directly. Instead, a Workflow (workflow.do) orchestrates the sequence, inputs, and outputs of multiple Actions.
This promotes modularity and a clear separation of concerns. Consider a new user onboarding process:
This sequence is a Workflow. If you need to change your CRM provider, you only update the add-user-to-crm Action. The rest of the workflow remains untouched. This is the essence of building resilient, scalable API automation.
The possibilities are virtually limitless. If you can script it, you can turn it into an Action. Common use cases include:
By encapsulating these tasks as atomic actions, you build a powerful, understandable, and scalable automation architecture. You stop writing one-off scripts and start building a true library of Services-as-Software.
Ready to DO MORE, FASTER? Start breaking down your complex processes into simple, atomic actions and discover the power of agentic workflows on the .do platform.