Command Proxy Generation
The proxy generator creates TypeScript command classes that provide type-safe command execution with React hook integration.
Supported Approaches
Commands can be implemented using two approaches, both of which are supported by the proxy generator:
- Controller-based: Commands in ASP.NET Core controllers using
[HttpPost]attributes - Model-bound: Simplified approach where a type represents the command directly
For detailed information on implementing commands, see the Commands documentation.
How Commands are Discovered
Controller-based Commands
The generator discovers controller-based commands by looking for:
- Methods marked with
[HttpPost] - Parameters marked with
[FromBody],[FromRoute], or[FromQuery]
See Controller-based Commands for implementation details.
Model-bound Commands
The generator discovers model-bound commands by finding types that:
- Are decorated with the
[Command]attribute - Have a
Handle()method (the command handler)
The type name becomes the command name, and all properties of the type become the command properties in the generated TypeScript.
See Model-bound Commands for implementation details.
Generated Command Structure
Generated command classes:
- Extend the
Commandbase class from@cratis/arc/commands - Include all properties from route parameters, query parameters, and body content
- Provide a static
use()method for React hook integration - Include the proper route based on the configuration
Generated Artifacts
For each command, the generator creates:
- Interface: An
ICommandNameinterface with all command properties - Class: A
CommandNameclass extendingCommand<ICommandName> - Route: The HTTP route derived from the controller route or model-bound configuration
Excluding Commands from Generation
To exclude specific controller-based commands from proxy generation, mark them with the [AspNetResult] attribute. This is useful when you want to handle the response manually or when the command returns a non-standard result.
Route Configuration
The generated route is affected by the CratisProxiesSkipCommandNameInRoute configuration option:
- When
false(default): The command type name is included in the route - When
true: The command type name is excluded from the route
Automatic Conflict Detection: When CratisProxiesSkipCommandNameInRoute is true, the proxy generator automatically detects if multiple commands exist in the same namespace (after skipping segments). If a conflict is detected, the command name is automatically included in the route to prevent route collisions. This behavior is consistent with the runtime endpoint mapping.
For example:
- Single command in namespace: Route is clean without type name (e.g.,
/api/orders) - Multiple commands in same namespace: Type names are added automatically (e.g.,
/api/orders/create-order,/api/orders/update-order)
See Configuration for more details on route configuration options.
Frontend Usage
The generated command proxies integrate with React through the use() static method, which returns:
- The command instance with all properties
- A setter function for updating command values
The command can then be executed using the execute() method, which returns a CommandResult with success/failure information and any validation errors.
For frontend usage patterns, see the @cratis/arc documentation.