Transmisión de datos entre estados con variables
Administración del estado con variables y JSONata
Step Functions ha agregado recientemente variables y JSONata para administrar el estado y transformar los datos.
Obtenga más información en la entrada del blog Simplifying developer experience with variables and JSONata in AWS Step Functions
En el siguiente vídeo se describen las variables y JSONata en Step Functions con un ejemplo de DynamoDB:
Con las variables y la salida de estado, puede transmitir datos entre los pasos de su flujo de trabajo.
Con las variables de flujo de trabajo, puede almacenar datos en un paso y recuperarlos en pasos futuros. Por ejemplo, puede almacenar una respuesta de la API que contenga los datos que puede que necesite más adelante. Por el contrario, la salida de estado solo se puede usar como entrada para el siguiente paso.
Resumen conceptual de las variables
Con las variables de flujo de trabajo, puede almacenar datos para consultarlos más adelante. Por ejemplo, el paso 1 puede almacenar el resultado de una solicitud de API para que una parte de esa solicitud pueda reutilizarse más adelante en el paso 5.
En el siguiente escenario, la máquina de estado obtiene los datos de una API una vez. En el paso 1, el flujo de trabajo almacena los datos de la API devueltos (hasta 256 KiB por estado) en una variable “x” para utilizarlos en pasos posteriores.
Sin variables, sería necesario pasar los datos a través de la salida del paso 1 al paso 2, al paso 3 y al paso 4 para usarlos en el paso 5. ¿Qué pasa si esos pasos intermedios no necesitan los datos? Pasar los datos de un estado a otro a través de las salidas y las entradas supondría un esfuerzo innecesario.
Con las variables, puede almacenar datos y utilizarlos en cualquier paso futuro. También puede modificar, reorganizar o añadir pasos sin interrumpir el flujo de los datos. Dada la flexibilidad de las variables, es posible que solo necesite usar la salida para devolver datos de los subflujos de trabajo Parallel y Map, y al final de la ejecución de la máquina de estado.
Estados que admiten variables
Los siguientes tipos de estado admiten Assign para declarar y asignar valores a las variables: Pass, Task, Map, Parallel, Choice, Wait.
Para configurar una variable, proporcione un objeto JSON con nombres y valores de variables:
"Assign": {
"productName": "product1",
"count" : 42,
"available" : true
}
Para hacer referencia a una variable, anexe al nombre un signo de dólar ($), por ejemplo, $productName.
Variable reservada: $states
Step Functions define una única variable reservada llamada $states. En los estados de JSONata, se asignan las siguientes estructuras a $states para su uso en las expresiones de JSONata:
# Reserved $states variable in JSONata states
$states = {
"input": // Original input to the state
"result": // API or sub-workflow's result (if successful)
"errorOutput": // Error Output (only available in a Catch)
"context": // Context object
}
Al introducir un estado, Step Functions asigna la entrada de estado a $states.input. El valor de $states.input se puede utilizar en todos los campos que acepten expresiones de JSONata. $states.input siempre hace referencia a la entrada de estado original.
Para los estados Task, Parallel, y Map:
-
$states.resulthace referencia al resultado sin procesar de la API o del subflujo de trabajo si se ha realizado correctamente. -
$states.errorOutputhace referencia a la salida de error si la API o el subflujo de trabajo produjo un error.$states.errorOutputse puede usar enAssignuOutputdel campoCatch.
Al crear, actualizar o validar la máquina de estado se detectarán los intentos de acceso a $states.result o $states.errorOutput en campos y estados que no son accesibles.
El objeto $states.context brinda a sus flujos de trabajo información sobre su ejecución específica, como StartTime, el token de la tarea y la entrada inicial del flujo de trabajo. Para obtener más información, consulte Acceso a los datos de ejecución desde el objeto Context en Step Functions .
Sintaxis de nombre de variable
Los nombres de las variables siguen las reglas de los identificadores Unicode, tal como se describe en el Unicode® Standard Annex #31
La convención de nombres de variables es similar a las reglas de JavaScript y otros lenguajes de programación.
Ámbito de la variable
Los flujos de trabajo de Step Functions evitan las condiciones de carrera con variables mediante el uso de un ámbito local del flujo de trabajo.
El ámbito local del flujo de trabajo incluye todos los estados dentro del campo Estados de una máquina de estado, pero no los estados dentro de los estados Parallel o Map. Los estados dentro de los estados Parallel o Map pueden hacer referencia a variables de ámbito externo, pero crean y mantienen sus propias variables y valores locales del flujo de trabajo independientes.
Las ramas Parallel y las iteraciones Map pueden acceder a los valores de las variables desde ámbitos externos, pero no tienen acceso a los valores de las variables de otras ramas o iteraciones simultáneas. Al gestionar los errores, el campo Assign de un Catch puede asignar valores a las variables del ámbito externo, es decir, el ámbito en el que existe el estado Parallel/Map.
Excepción: Los estados Distributed Map no pueden hacer referencia actualmente a variables en ámbitos externos.
Una variable existe en un ámbito si algún estado del ámbito le asigna un valor. Para evitar errores comunes, una variable asignada en un ámbito interno no puede tener el mismo nombre que una asignada en un ámbito externo. Por ejemplo, si el ámbito de nivel superior asigna un valor a una variable llamada myVariable, ningún otro ámbito (dentro de Map, Parallel) podrá asignarlo también a myVariable.
El acceso a las variables depende del ámbito actual. Los estados Parallel y Map tienen su propio ámbito, pero pueden acceder a variables de ámbitos externos.
Cuando se complete un estado Parallel o Map, todas sus variables quedarán fuera del ámbito y dejarán de ser accesibles. Utilice el campo Output para pasar los datos de las ramas Parallel y de las iteraciones Map.
Asignación de campo en ASL
El campo Assign en ASL se usa para asignar valores a una o más variables. El campo Assign está disponible en el nivel superior de cada estado (excepto Succeed y Fail), dentro de las reglas de estado Choice y dentro de los campos Catch. Por ejemplo:
# Example of Assign with JSONata
"Store inputs": {
"Type": "Pass",
"Next": "Get Current Price",
"Comment": "Store the input desired price into a variable: $desiredPrice",
"Assign": {
"desiredPrice": "{% $states.input.desired_price %}",
"maximumWait": "{% $states.input.max_days %}"
}
},
El campo Assign toma un objeto JSON. Cada campo de nivel superior nombra una variable para asignarla. En los ejemplos anteriores, los nombres de las variables son desiredPrice y maximumWait. Cuando se utiliza JSONata, {% ... %} indica una expresión de JSONata que puede contener variables o expresiones más complejas. Para obtener más información sobre las expresiones de JSONata, consulte la documentación de JSONata.org
Cuando se utiliza JSONata como lenguaje de consulta, el siguiente diagrama muestra cómo se procesan en paralelo los campos Assign y Output. Tenga en cuenta lo que implica: la asignación de valores variables no afectará a la salida del estado.
En el siguiente ejemplo de JSONata se recupera order.product desde la entrada del estado. La variable currentPrice se establece en un valor del resultado de la tarea.
# Example of Task with JSONata assignment from result
{
"Type": "Task",
...
"Assign": {
"product": "{% $states.input.order.product %}",
"currentPrice": "{% $states.result.Payload.current_price %}"
},
"Next": "the next state"
}
Nota: No puede asignar un valor a una parte de una variable. Por ejemplo, puede "Assign":{"x":42}, pero no puede "Assign":{"x.y":42} o "Assign":{"x[2]":42}.
Orden de evaluación en un campo de asignación
Todas las referencias de variables en los estados de Step Functions utilizan los valores tal como estaban en la entrada del estado.
El hecho anterior es importante para entender cómo el campo Assign asigna valores a una o más variables. En primer lugar, se calculan los nuevos valores y, a continuación, Step Functions asigna los nuevos valores a las variables. Los nuevos valores de las variables estarán disponibles a partir del siguiente estado. Por ejemplo, considere el siguiente campo Assign:
# Starting values: $x=3, $a=6
"Assign": {
"x": "{% $a %}",
"nextX": "{% $x %}"
}
# Ending values: $x=6, $nextX=3
En el ejemplo anterior, se asigna la variable x y se hace referencia a ella.
Recuerde que primero se evalúan todas las expresiones y, a continuación, se realizan las asignaciones. Los valores recién asignados estarán disponibles en el siguiente estado.
Repasemos el ejemplo en detalle. Supongamos que, en un estado anterior, a $x se le asignó un valor de tres (3) y a $a se le asignó a un valor de seis (6). Los siguientes pasos describen el proceso:
-
Todas las expresiones se evalúan utilizando los valores actuales de todas las variables.
La expresión
"{% $a %}"se evaluará como 6 y"{% $x %}"se evaluará como 3. -
A continuación, se realizan las asignaciones:
A
$xse le asignará el valor seis (6)A
$nextXse le asignará tres (3)
Nota: Si $x no se hubiera asignado previamente, el ejemplo generaría un error porque $x estaría sin definir.
En resumen, Step Functions evalúa todas las expresiones y, a continuación, realiza las asignaciones. No importa el orden en que aparecen las variables en el campo Assign.
Límites
El tamaño máximo de una única variable es de 256 KiB, tanto para los flujos de trabajo estándar como rápidos.
El tamaño máximo combinado de todas las variables de un único campo Assign también es de 256 KiB. Por ejemplo, puede asignar X e Y a 128 KiB, pero no puede asignar X e Y a 256 KiB en el mismo campo Assign.
El tamaño total de todas las variables almacenadas no puede superar los 10 MiB por ejecución.
Uso de variables en los estados de JSONPath
Las variables también están disponibles en los estados que utilizan JSONPath como lenguaje de consulta.
Puede hacer referencia a una variable en cualquier campo que acepte una expresión de JSONPath (sintaxis $. o $$.), a excepción de ResultPath, que especifica una ubicación en la entrada de estado para inyectar el resultado del estado. No se pueden usar variables en ResultPath.
En JSONPath, el símbolo $ hace referencia al valor “actual” y $$ representa el objeto Context del estado. Las expresiones de JSONPath pueden empezar con $. como en $.customer.name. Puede acceder al contexto con $$. como en $$.Execution.Id.
Para hacer referencia a una variable, también se utiliza el símbolo $ antes del nombre de la variable, por ejemplo, $x o $order.numItems.
En los campos de JSONPath que aceptan funciones intrínsecas, las variables se pueden utilizar en los argumentos, por ejemplo States.Format('The order number is {}', $order.number).
En el siguiente diagrama se ilustra cómo el paso de asignación de una tarea de JSONPath se produce al mismo tiempo que el ResultSelector:
Asignación de variables en JSONPath
Las asignaciones de variables de JSONPath se comportan de forma similar a las plantillas de carga útil. Los campos que terminan con .$ indican que el valor es una expresión de JSONPath que Step Functions evalúa como un valor durante la ejecución de la máquina de estado (por ejemplo: $.order..product y $.order.total).
# Example of Assign with JSONPath
{
"Type": "Task",
...
"Assign": {
"products.$": "$.order..product",
"orderTotal.$": "$.order.total"
},
"Next": "the next state"
}
En el caso de los estados de JSONPath, el valor de $ en un campo Assign depende del tipo de estado. En los estados Task, Map, Parallel, $ hace referencia al resultado de la API/subflujo de trabajo. En el estado Choice y Wait, $ hace referencia a la entrada efectiva, que es el valor después de que InputPath se haya aplicado a la entrada de estado. Para Pass, $ hace referencia al resultado, ya sea generado por el campo Result o por los campos InputPath/Parameters.
En el siguiente ejemplo de JSONPath se asigna un objeto JSON a la variable details, el resultado de la expresión de JSONPath $.result.code a resultCode y el resultado de la expresión de JSONPath States.Format('Hello {}', $customer.name) a message. Si estaba en un estado Task, entonces $ en $.order.items y $.result.code hace referencia al resultado de la API. A la variable startTime se le asigna un valor del objeto Context, $$.Execution.StartTime.
"Assign": {
"details": {
"status": "SUCCESS",
"lineItems.$": "$.order.items"
},
"resultCode.$": "$.result.code",
"message.$": "States.Format('Hello {}', $customer.name)",
"startTime.$": "$$.Execution.StartTime"
}