Action-oriented APIs

Action-oriented APIs

In a typical REST API, the HTTP method carries all the meaning: POST creates, PUT updates, DELETE removes. The request body is an anonymous JSON payload shaped like the resource.

With commands, the request body is the action — a named, typed object that describes what the user intends to do. A POST /orders that accepts a CreateOrderCommand is just as much a command as a POST /reports/:generate that accepts a GenerateReportCommand.

Creating an invoice is an action. Deleting a draft is an action. Generating a report is an action. Some map to standard REST verbs, some to custom routes — but they’re all commands. The difference isn’t in the URL style. It’s that every mutation has a class name, a UUID, and a paper trail.

What this gives you

Named operations

The command log says CreateOrderCommand or GenerateReportCommand, not "POST to /orders." You can query, monitor, and analyze by operation name.

Consistent contract

Every command carries cmdUuid and cmdSourceRef. The structure is flat and form-friendly — it doesn’t need to mirror the domain model.

Works beyond HTTP

The same command class can be executed from a controller, a background job, a message handler, or a retry mechanism.

Composable

One command can trigger others. cmdSourceRef links them — you can trace how a single user action propagated through the system.

Standard REST is fine

Not every endpoint needs a custom action-style route. A POST /orders, DELETE /orders/{id}, or PATCH /orders/{id} are all commands — standard REST with a named, traceable body. The command model adds value whenever the operation is worth recording — which, for state-changing operations, is most of the time.