Saltar al contenido

Acciones

Esta página está traducida del inglés. Leer la página en inglés

Una acción es código de servidor al que puede llamar una pantalla, una tabla, un formulario, un comando, la API JSON o un agente. #[action] declara quién puede llamarla; el framework lo comprueba antes de que se ejecute el código.

Declarar una acción

#[action(permission = "stock.product.read")]
pub async fn search_products(q: DataQuery, store: ProductStore) -> Result<Page<Product>> {
    Ok(q.apply(store.all()?))
}

#[action(permission = "stock.product.write", audit)]
pub async fn save_product(product: Valid<Product>, store: ProductStore) -> Result<Product> {
    store.save(product.into_inner())
}
  • El primer argumento es la entrada. Viene del cliente, así que el framework la lee como JSON no confiable.
  • Todos los demás argumentos se inyectan: Ctx o un Service registrado.
  • El tipo de retorno es Result<T>.

Acceso

Cada acción declara exactamente una de estas opciones:

OpciónSignificado
permission = "feature.resource.verb"La identidad necesita este permiso
publicCualquiera, incluidos los usuarios que no han iniciado sesión

Una acción sin acceso no compila. Los nombres de permiso van en minúsculas y separados por puntos, como sales.order.write.

Otras opciones:

OpciónSignificado
auditEscribe un registro de auditoría en cada llamada
reauthEl usuario debe haber iniciado sesión hace poco (App::reauth_within)

Errores

ErrorEstadoUso
Error::NotFound404El registro no existe o el usuario no debe saber que existe
Error::Forbidden403Acceso denegado
Error::Denied(t!("..."))403Denegado con un motivo que el usuario puede leer
Error::Conflict409La versión de la fila cambió desde que se cargó el formulario
Error::Validation(errors)422Errores de campo, mostrados junto a los campos
Error::Internal("detail")500El detalle va solo al registro del servidor

Un error de campo desde código:

let mut errors = ValidationErrors::default();
errors.add(Product::code, t!("stock.code_taken", code = product.code));
return Err(errors.into());

Listas

Las listas reciben un DataQuery y devuelven Page<M>. Una acción de lista nunca devuelve todas las filas; la tabla pide páginas y el servidor limita el tamaño de página sea lo que sea que envíe el cliente.

El contexto

Ctx es la petición: ctx.identity(), ctx.locale(), ctx.time_zone(), ctx.now(), ctx.today(), ctx.tenant(), ctx.license(), ctx.config(), ctx.theme() y ctx.t(&text). Usa ctx.now() y ctx.today() en lugar del reloj del sistema, para que las pruebas puedan fijar la hora con App::fixed_now.

Dónde se usan las acciones

  • DataGrid::of(action) carga filas; .edit_with(action), .row_action(...) y .bulk_action(...) las cambian.
  • Form::submit(label, action) guarda un formulario.
  • ActionButton::new(label, action, input) ejecuta una acción desde un botón.
  • Command::action(...) ejecuta una desde la paleta de comandos o un atajo.
  • Feature::api(action) la publica como JSON (consulta API y OpenAPI).
  • Feature::search(action) añade una búsqueda de servidor a la paleta de comandos.

Todas las rutas ejecutan las mismas comprobaciones: CSRF para las llamadas del navegador, los guards de la feature, el acceso de la acción y después los interceptores.