In modern development, the line between internal business logic and external services is blurring. You write a brilliant piece of code to enrich user data, process a payment, or generate a report. It works perfectly within your system. But what happens when your marketing team wants to trigger it from a webhook, a partner needs to integrate with it, or your new front-end requires it as a data source?
Traditionally, this is where the real work begins. You'd need to wrap your logic in an HTTP server, configure an API gateway, implement authentication and rate-limiting, and manage the deployment pipeline. A task that took an hour to code can take days to deploy as a secure, scalable service.
At .do, we believe in Business-as-Code. Your core business processes should be defined as clean, reusable, and observable units of code. Building on our foundation of atomic action.do units, we're introducing the final piece of the puzzle: service.create. It’s the command that closes the gap, turning your tested business logic into a live API in minutes.
Before we can expose a service, we need something to expose. The .do platform is built on the concept of the atomic action. An action.do is the smallest, indivisible unit of work in any agentic workflow. It's a self-contained function that performs one single, specific task.
Think of it as the ultimate building block for automation. Each block is:
Here’s how you might define an action to enrich a user profile using Clearbit. This is your core business logic, encapsulated.
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);
This enrich-user-profile action is now a first-class citizen on the .do platform. It’s versioned, secure, and ready to be used in any internal workflow. But how do we make it available to the outside world?
This is where the magic happens. Your action.do contains the "what," and service.create provides the "how." It instantly wraps any action.do or workflow.do in a secure, scalable, public-facing HTTP API endpoint, handling all the infrastructural boilerplate for you.
Let's take the enrichUserAction we just created and expose it as a public service.
// Assuming 'enrichUserAction.id' holds the ID of our action from the previous step
const apiService = await do.service.create({
name: 'user-enrichment-api',
description: 'Public API for enriching user profiles.',
entrypoint: {
type: 'action', // Can also be 'workflow'
id: enrichUserAction.id,
},
// The .do platform handles authentication, endpoint generation,
// DNS, scaling, and security automatically.
});
console.log('API is live at:', apiService.endpointUrl);
// Example output: https://user-enrichment-api.svc.do.co/invoke
That's it.
With one simple command, you've created a service.do. The .do platform automatically:
You wrote the business logic. We delivered the API.
The ability to seamlessly transition from an internal action.do to a public service.do fundamentally changes how you build and deploy software.
1. Unmatched Speed: Go from an idea to a production-ready API in minutes, not days or weeks. This allows for rapid prototyping and iteration.
2. Focus on Value: Your developers focus on writing business logic—the code that actually creates value—not on managing API gateways, configuring servers, or writing authentication boilerplate.
3. Abstract Away Infrastructure: While an action handler feels like a simple serverless function, a service.do is a fully managed API product. It abstracts away not just servers, but the entire service delivery lifecycle, including security, versioning, and monitoring.
4. The "Services-as-Software" Paradigm: This workflow embodies our vision for Services-as-Software. Your operational capabilities are defined in code (action.do), composed into complex processes (workflow.do), and published for consumption (service.do), creating a truly programmable business.
The power of service.create isn't limited to a single atomic action. You can just as easily expose an entire workflow.do.
Imagine a workflow named onboard-new-customer that chains together several actions:
By passing the workflow's ID to service.create, you can expose this entire multi-step process as a single, powerful API endpoint. One API call can now trigger a complex, resilient, and observable business workflow.
Ready to stop wrestling with infrastructure and start shipping value? service.create is more than a feature; it's a new way of thinking about building and delivering services. Define. Execute. Expose. Repeat.
Get started with the .do platform today and turn your business logic into live APIs before your coffee gets cold.