Skip to content

Model-Bound Operations

Arc supports minimal API-style endpoints for commands and queries, called model-bound operations. These endpoints are registered automatically by the Arc infrastructure and follow a convention-based naming scheme (Execute<TypeName>).

Because model-bound endpoints do not use traditional controller actions, the standard CommandResultOperationTransformer and QueryResultOperationTransformer transformers do not apply to them. The ModelBound.CommandOperationTransformer and ModelBound.QueryOperationTransformer fill this gap.

Model-bound transformers are included automatically when you call AddConcepts():

builder.Services.AddOpenApi(options => options.AddConcepts());

They can also be registered independently:

builder.Services.AddOpenApi(options => options.AddModelBoundOperationTransformers());

The ModelBound.CommandOperationTransformer matches operations whose operationId starts with Execute and resolves the command type from the registered ICommandHandlerProviders.

For matched operations it:

  1. Sets the requestBody to a schema of the command type.
  2. Sets the 200 response schema to CommandResult or CommandResult<T> (depending on the handler return type).
  3. Adds 400, 403, and 500 error response schemas.
// The command is automatically discovered and the endpoint is documented
[Command]
public record CreateInvoice(CustomerId Customer, decimal Amount)
{
public Task Handle() { ... }
}

The ModelBound.QueryOperationTransformer matches operations whose operationId starts with Execute and resolves the query performer from the registered IQueryPerformerProviders.

For matched operations it:

  1. Adds each query parameter from the performer’s parameter list as a query string parameter.
  2. Adds paging and sorting parameters when IQueryPerformer.SupportsPaging is true.
  3. Sets the 200 response schema to QueryResult.
  4. Adds 400, 403, and 500 error response schemas.

For query performers that support paging, the following query parameters are added:

ParameterTypeDescription
sortbystringField name to sort by
sortDirectionstring (asc | desc)Sort direction
pageSizeintegerNumber of items per page
pageintegerPage number (0-based)