In modern software development, we love building blocks. Components, microservices, and functions allow us to create robust, maintainable systems by focusing on one small piece of the puzzle at a time. This is the core philosophy behind the .do platform: encapsulate any single, repeatable task into a self-contained, atomic action.do.
You can create an action to send an email, add a user to a database, or query an API. This is incredibly powerful. For example, defining an action to send a welcome email is clean and straightforward:
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({...});
const result = { success: true, messageId: `msg_${Date.now()}` };
console.log('Email sent successfully:', result.messageId);
return result;
},
});
But what happens when a business process involves more than one step? A new user signing up isn't just one action; it's a cascade of events. This is where the true power of the .do platform shines: moving from single actions to orchestrated systems with workflow.do.
An atomic action is the fundamental unit of work—the verb. It's designed to do one thing and do it well. But real-world processes are sentences, paragraphs, and entire stories. You don't just "send an email." You "create a user," then "send a welcome email," then "add them to your CRM," and finally "notify the team on Slack."
Trying to cram all that logic into a single, monolithic action would defeat the purpose. It would become brittle, hard to test, and impossible to reuse.
This is where workflow.do comes in. It's the orchestrator.
If action.do is a Lego brick, workflow.do is the instruction manual that shows you how to connect those bricks to build something amazing. It defines the sequence, logic, and flow of how multiple actions run together to accomplish a complex task.
Let's expand on our send-welcome-email action. A complete user onboarding process might involve several distinct, atomic actions:
With workflow.do, you don't write complex imperative code to chain these together. Instead, you declaratively define the flow. A workflow.do file might look something like this (conceptual example):
name: new-user-onboarding
description: Handles the complete process for onboarding a new user.
trigger:
type: api # This workflow can be triggered by an API call
inputs:
name: string
email: string
company: string
steps:
- name: createUser
action: create-user-in-db # Reference an existing action.do
inputs:
name: ${{ inputs.name }}
email: ${{ inputs.email }}
- name: sendWelcomeEmail
action: send-welcome-email
needs: [createUser] # This step runs after createUser completes
inputs:
name: ${{ inputs.name }}
email: ${{ inputs.email }}
- name: addToCrm
action: add-user-to-crm
needs: [createUser]
inputs:
email: ${{ inputs.email }}
company: ${{ inputs.company }}
- name: notifyTeam
action: notify-sales-on-slack
needs: [addToCrm] # Runs after user is in the CRM
inputs:
message: "🎉 New User Signup: ${{ inputs.name }} from ${{ inputs.company }}"
This approach provides immense benefits:
This model of combining action.do and workflow.do is the practical application of Business-as-Code. Your core business processes are no longer hidden in the minds of employees or scattered across monolithic applications. They are defined as version-controlled, testable, and auditable code.
These orchestrated systems become your agentic workflows. They can be triggered by API calls, run on a schedule, or react to events, autonomously executing business logic. This is the next evolution of API automation and workflow orchestration—moving beyond simple scripts to build intelligent, adaptable systems from simple, powerful building blocks.
So, while your journey on the .do platform starts with a single atomic action, the destination is a universe of complex, automated systems. What workflow will you build first?
What is an 'atomic action' on the .do platform?
An atomic action is the smallest, indivisible unit of work in a workflow. It's a self-contained, reusable function designed to perform a single task reliably, like 'send an email', 'create a user', or 'query a database'.
How are Actions different from traditional serverless functions?
Actions on .do are supercharged functions. They are automatically instrumented with logging, error handling, retries, and versioning. They are designed to be discovered and composed into larger workflows, effectively turning your business logic into manageable code.
Can an Action call other Actions?
While Actions are designed to be atomic, complex logic is best handled by orchestrating multiple Actions within a Workflow (workflow.do). This promotes modularity, reusability, and a clearer separation of concerns in your automation architecture.
What kind of tasks can I build as an Action?
Virtually any task you can script. Common examples include interacting with third-party APIs (e.g., Stripe, Slack, Salesforce), performing database operations, running data transformations, or executing machine learning model inferences. If you can code it, you can make it an Action.