In the world of software architecture, the microservices paradigm has been a dominant force for nearly a decade. By breaking down monolithic applications into smaller, independently deployable services, teams have unlocked unprecedented agility and scalability. But what happens when you need to orchestrate the tasks within and between these services? What is the right level of abstraction for business process automation and the emerging world of agentic workflows?
The answer lies in thinking even smaller.
While microservices manage broad business capabilities, a new, more granular concept is emerging as the key to modern automation: the Atomic Action. This is the fundamental building block on the .do platform—the indivisible, atomic unit of work.
A microservice is an architectural style that structures an application as a collection of loosely coupled services. Think of an e-commerce platform: you might have a UserService, a ProductService, and an OrderService.
Key Characteristics:
Microservices are brilliant for building large, complex applications. But using them to define a simple, sequential business process can be like using a sledgehammer to crack a nut. The overhead of inter-service communication, distributed transactions, and deployment can quickly become overwhelming for straightforward automation tasks.
An Atomic Action, as defined on the .do platform, is the smallest, self-contained, and executable unit of a workflow. It's designed to do one thing and do it exceptionally well. It's not a service; it's a single, programmable task.
Let's look at an example. Instead of an entire EmailService, you'd have a specific Atomic Action like send-welcome-email.
import { Action } from '@do-co/agent';
// Define a new atomic action to send a welcome email
const sendWelcomeEmail = new Action('send-welcome-email', {
title: 'Send Welcome Email',
description: 'Sends a standardized welcome email to a new user.',
input: {
to: { type: 'string', required: true },
name: { type: 'string', required: true },
},
async handler({ to, name }) {
console.log(`Sending email to ${to}...`);
// Actual email sending logic (e.g., using an SMTP service) would go here
const message = `Welcome to the platform, ${name}!`;
console.log(message);
return { success: true, messageId: `msg_${Date.now()}` };
},
});
// Execute the action with specific inputs
const result = await sendWelcomeEmail.run({
to: 'new.user@example.com',
name: 'Alex',
});
console.log(result);
Notice the key properties:
The core difference between microservices and atomic actions is the level of abstraction and intended purpose.
| Feature | Microservice | Atomic Action |
|---|---|---|
| Scope | A broad business capability (e.g., "Payments") | A single, discrete task (e.g., refund-payment) |
| Granularity | Coarse-grained | Fine-grained |
| Purpose | To build a scalable, decoupled application backend. | To serve as a reusable step in an automated workflow. |
| Overhead | High (server, database, deployment pipeline). | Minimal (code-defined, executed by a platform). |
| Orchestration | Complex inter-service communication (e.g., sagas). | Simple, declarative composition within a workflow. |
This granular, action-oriented approach is uniquely suited for building the next generation of automation and AI-driven workflows.
Ultimate Reusability: An action like create-jira-ticket or query-database can be composed into hundreds of different workflows without any changes. This dramatically speeds up development.
Clarity and Maintainability: Business logic is no longer hidden inside a monolithic service. It becomes a clear, readable sequence of actions: Fetch User Data -> Check Subscription Status -> Send Renewal Email. Debugging and modification become trivial.
Platform-Managed Scale: You define the action's logic. The .do platform handles the rest: execution, retries, logging, and scaling. You focus on the what, not the how.
The Perfect Toolkit for AI Agents: For an AI agent to perform tasks, it needs a well-defined set of "tools." Atomic actions provide exactly that. An agent can be given a library of actions (post-to-slack, update-crm-record, summarize-text) and can intelligently choose and chain them together to accomplish a complex goal.
Atomic Actions don't replace microservices. They complement them perfectly. Your robust UserService microservice can expose a set of API endpoints. You can then create a series of Atomic Actions on the .do platform that act as safe, workflow-friendly interfaces to that service: get-user-by-id, deactivate-user, update-user-permissions.
The action becomes the bridge, transforming your powerful backend capabilities into composable, Lego-like bricks for anyone to build powerful automations.
By focusing on the atomic unit of work, we gain the clarity, reusability, and scalability needed to build truly powerful and intelligent Agentic Workflows.
What is an atomic action in the .do platform?
An atomic action is the smallest, indivisible unit of work in a workflow. It's a self-contained, executable task—like sending an email, querying a database, or calling an external API. Each action is designed to do one thing well.
How are actions different from workflows?
Actions are the individual steps, while workflows are the orchestration of multiple actions in a specific sequence or logic. You build complex workflows by composing simple, reusable actions together.
Can I create my own custom actions?
Absolutely. The .do SDK allows you to define custom actions with specific inputs, outputs, and business logic. This transforms your unique business operations into reusable, programmable building blocks for any workflow.