Skip to content

Commands

Commands represent actions you want to perform against the system. Arc generates their HTTP surface from model-bound commands, and in C# also from discovered controller actions. Either style can use validation and authorization; neither requires Chronicle or event sourcing.

Commands provide a structured way to:

  • Encapsulate business operations and state changes
  • Validate input before execution
  • Track changes from original values
  • Integrate with React’s rendering pipeline
  • Handle authorization and error scenarios

Backend fragment: these are the declarations the proxy below is generated from.

public record OpenDebitAccount(AccountId AccountId, AccountName Name, CustomerId Owner);

View C# snippet source on GitHub

The backend tabs reach the shared generated-command runtime from different starting points. The C# record is a payload DTO: it requires an already-defined controller endpoint accepting it, because a record alone is not enough for proxy discovery. The JVM has no controller-based discovery, so the model-bound @Command is the endpoint. TypeScript’s source preview generates from decorated @command() classes with a handle() method; see its generator setup. For a complete model-bound C# example, follow getting started.

Consumer fragment: call this hook inside a component, and execute from its event handler. This example assumes string-backed AccountId and CustomerId; use Fundamentals Guid values instead if the generated model maps Guid-backed concepts.

import { OpenDebitAccount } from './generated/commands';
export function OpenAccount() {
const [command] = OpenDebitAccount.use({
accountId: 'a23edccc-6cb5-44fd-a7a7-7563716fb080',
name: 'My Account',
owner: '84cda809-9201-4d8c-8589-0be37c6e3f18'
});
async function open() {
const result = await command.execute();
console.log(result.isSuccess ? 'Opened.' : 'Could not open account.');
}
return <button onClick={() => void open()}>Open account</button>;
}

Command fetches include httpHeadersCallback headers configured in Arc. Supply Authorization or application headers there; cookies are browser-managed, not configurable Cookie request headers.

Commands are automatically generated from your backend using the proxy generator. The generator scans HTTP Post actions during compile time and creates TypeScript classes that:

  • Match your backend command structure
  • Provide type-safe properties
  • Include validation support
  • Offer a .use() method for React integration
  • Track changes automatically

See Proxy Generation for setup details.

When executed, commands return a CommandResult with detailed information about the outcome:

const result = await command.execute();
if (result.isSuccess) {
console.log('Success!', result.response);
} else {
if (!result.isAuthorized) {
// Handle authorization failure
}
if (!result.isValid) {
// Handle validation errors
}
}

For comprehensive details, see Command Result documentation.

TopicDescription
React UsageUsing the .use() hook in React components (recommended).
Data BindingBinding to command properties and managing initial values for change tracking.
ValidationPre-flight validation, progressive validation, and error handling.
Command ScopeTracking changes across multiple commands in composite UIs.
Imperative UsageAdvanced direct instantiation for non-React scenarios.