

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# 変数を使用したステート間のデータ受け渡し
<a name="workflow-variables"></a>

**変数と JSONata によるステート管理**  
Step Functions では最近、ステート管理とデータ変換のために変数と JSONata が追加されました。  
詳細については、ブログ記事「[Simplifying developer experience with variables and JSONata in AWS Step Functions](https://aws.amazon.com/blogs/compute/simplifying-developer-experience-with-variables-and-jsonata-in-aws-step-functions/)」を参照してください。  
 次のビデオでは、Step Functions の変数と JSONata を DynamoDB の例で説明しています。  




 変数とステートの出力を使用すると、ワークフローのステップ間でデータを受け渡すことができます。

 ワークフロー変数を使用すると、あるステップでデータを保存し、後のステップでそのデータを取得できます。例えば、後で必要になる可能性のあるデータを含む API レスポンスを保存できます。逆に、ステートの出力は、直後のステップへの入力としてのみ使用できます。

## 変数の概念的概要
<a name="conceptual-overview-of-variables"></a>

 ワークフロー変数を使用すると、後で参照するためにデータを保存できます。例えば、ステップ 1 で API リクエストの結果を保存し、それを後のステップ 5 で再利用できます。

 次のシナリオでは、ステートマシンは API からデータを 1 回取得します。ステップ 1 で、ワークフローは返された API データ (ステートごとに最大 256 KiB) を変数「x」に保存し、後続のステップで使用できるようにします。

 変数を使用せずに同じことを行おうとすると、ステップ 1 → 2 → 3 → 4 → 5 というすべてのステップでデータを渡す必要があります。それらの中間ステップでそのデータが必要ない場合はどうなるでしょうか。出力と入力を通じてステートからステートへデータを渡すことは無駄な処理となります。

 変数を使用すると、一度データを保存しておけば、後続のどのステップからでもそのデータにアクセスできます。データフローを中断することなく、ステップを変更、再配置、または追加することもできます。変数の柔軟性を活かせば、**Output** の使用は、Parallel や Map のサブワークフローからデータを返すときや、ステートマシンの実行終了時のみで済むようになります。

 ![\[Diagram showing step 1 assigning a value to $x, used in step 5.\]](http://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/images/vars-diag-opt1.png)

 **変数をサポートするステート **

 *Pass、Task、Map、Parallel、Choice、Wait* のステートタイプでは、`Assign` を使用して変数の宣言と値の代入ができます。

 変数を設定するには、変数の名前と値を含む JSON オブジェクトを指定します。

```
"Assign": {
  "productName": "product1",
  "count" : 42,
  "available" : true
}
```

 変数を参照するには、名前の前にドル記号 (`$`) を付けます (例: `$productName`)。

## 予約変数: \$1states
<a name="reserved-variable-states"></a>

 Step Functions では、**`$states`** という名前の予約変数が定義されています。JSONata のステートでは、次の構造が JSONata の式用に `$states` に割り当てられます。

```
# 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
}
```

 ステートの開始時に、Step Functions ではステートの入力が **`$states.input`** に割り当てます。`$states.input` の値は、JSONata 式を受け入れるすべてのフィールドで使用できます。`$states.input` は常にステートの入力の元の値を参照します。

 `Task`、`Parallel`、および `Map` ステートの場合:
+ API またはサブワークフローが成功した場合、**`$states.result`** はその未加工の結果を参照します。
+ API またはサブワークフローが失敗した場合、**`$states.errorOutput`** はそのエラー出力を参照します。

  `$states.errorOutput` は `Catch` フィールドの `Assign` または `Output` で使用できます。

アクセスできないステートやフィールドで `$states.result` や `$states.errorOutput` にアクセスしようとすると、ステートマシンの作成、更新、検証時にキャッチされます。

`$states.context` オブジェクトは、`StartTime`、タスクトークン、初期ワークフロー入力など、特定の実行に関する情報をワークフローに提供します。詳細については[Step Functions の Context オブジェクトから実行データにアクセスする](input-output-contextobject.md)を参照してください。

## 変数名の構文
<a name="variable-name-syntax"></a>

 変数名は、[Unicode® Standard Annex \$131](https://unicode.org/reports/tr31/) で説明されている Unicode 識別子のルールに従います。変数名の最初の文字は Unicode ID\$1Start 文字であり、2 番目以降の文字は Unicode ID\$1Continue 文字である必要があります。変数名の最大長は 80 です。

 変数名の規則は JavaScript などのプログラミング言語のルールと似ています。

## 変数のスコープ
<a name="variable-scope"></a>

 Step Functions ワークフローは、*workflow-local* スコープを使用して、変数との競合状態を回避します。

ワークフローローカルスコープには、ステートマシンの **States** フィールド内のすべてのステートが含まれますが、Parallel または Map ステート内のステートは含まれません。Parallel または Map ステート内のステートは外側のスコープの変数を参照できますが、それぞれ独立したワークフローローカル変数と値を作成して保持します。

`Parallel` ブランチと `Map` イテレーションは、**外側のスコープ**の変数値にはアクセスできますが、他の同時実行中のブランチやイテレーションの変数値にはアクセスできません。エラー処理時、`Catch` 内の `Assign` フィールドは、外側のスコープ (Parallel/Map ステートが存在するスコープ) にある変数に値を割り当てることができます。

 例外: **Distributed Map ステート**は、現在のところ外側のスコープにある変数を参照できません。

 スコープ内のいずれかのステートが変数に値を割り当てると、その変数はスコープ内に存在します。よくあるエラーを避けるために、内側のスコープで割り当てられた変数は、外側のスコープで割り当てられた変数と同じ名前にすることはできません。例えば、トップレベルのスコープで `myVariable` という変数に値を割り当てている場合、他のスコープ (`Map` や `Parallel` の中) で同じ `myVariable` に値を割り当てることはできません。

 変数へのアクセスは現在のスコープによって決まります。Parallel および Map ステートには独自のスコープがありますが、外側のスコープの変数にはアクセスできます。

 Parallel または Map ステートが完了すると、それらのスコープ内の変数はスコープ外となり、アクセスできなくなります。Parallel のブランチやマップのイテレーションからデータを渡すには、**Output フィールド**を使用します。

## ASL の Assign フィールド
<a name="assign-field-in-asl"></a>

 ASL の `Assign` フィールドは、1 つ以上の変数に値を割り当てるために使用されます。`Assign` フィールドは、各ステートのトップレベル (`Succeed` と `Fail` を除く)、`Choice` ステートのルール内、および `Catch` フィールド内で使用できます。例: 

```
# 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 %}"
    }
},
```

 `Assign` フィールドは JSON オブジェクトを受け取ります。トップレベルの各フィールドが、割り当て先となる変数の名前になります。前の例では、変数名は `desiredPrice` と `maximumWait` です。JSONata を使用する場合、`{% ... %}` は JSONata 式を示し、これには変数やより複雑な式が含まれることがあります。JSONata 式の詳細については、[JSONata.org のドキュメント](https://docs.jsonata.org/overview.html)を参照してください。

 次の図では、**JSONata** をクエリ言語として使用する場合、**Assign** と **Output** のフィールドが並行して処理される方法を示しています。重要: *変数に値を割り当てても、ステートの Output には影響しません。*

 ![\[Diagram showing a comparison of JSONPath and JSONata flow.\]](http://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/images/vars-jsonata.png)

 次の JSONata の例では、ステートの入力から `order.product` を取得しています。変数 `currentPrice` には、タスクの結果から取得した値が割り当てられます。

```
# 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"
}
```

 注: 変数の一部分に値を割り当てることは**できません**。例えば、`"Assign":{"x":42}` はできますが、`"Assign":{"x.y":42}` や `"Assign":{"x[2]":42}` はできません。

## Assign フィールド内での評価順序
<a name="evaluation-order-in-an-assign-field"></a>

Step Functions では、ステート内のすべての変数参照は、**ステート開始時**の値を使用します。

この前提は、`Assign` フィールドが複数の変数にどのように値を代入するかを理解するために重要です。まず、新しい値が計算されます。次に Step Functions が新しい値を変数に割り当てます。新しい変数値は、**次の**ステートから使用できるようになります。例えば、次のような `Assign` フィールドを考えてみましょう。

```
# Starting values: $x=3, $a=6

"Assign": {
  "x": "{% $a %}",
  "nextX": "{% $x %}"
}

# Ending values: $x=6, $nextX=3
```

前の例では、変数 `x` は割り当てと同時に参照もされています。

すべての式は***まず評価***されてから、割り当てられることに注意してください。その後、新しく割り当てられた値は**次の**ステートで使用できるようになります。

この例を詳しく見ていきましょう。前のステートで、`$x` には 3 が割り当てられ、`$a` には 6 が割り当てられたとします。このプロセスのステップを以下に示します。

1. すべての式は、すべての変数の**現在の**値を使用して評価されます。

   式 `"{% $a %}"` は 6 に評価され、`"{% $x %}"` は 3 に評価されます。

1. 次に、割り当てが行われます。

   `$x` に値 6 が割り当てられます。

   `$nextX` に値 3 が割り当てられます。

 注: `$x` が事前に割り当てられていなかった場合、`$x` が*未定義*となるため、この例は**失敗**します。

 まとめると、Step Functions は**すべて**の式を評価してから、割り当てを行います。`Assign` フィールド内での変数の出現順序は**関係ありません**。

## 制限
<a name="limits"></a>

 1 つの変数の最大サイズは、Standard ワークフローと Express ワークフローの両方で 256 KiB です。

 1 つの `Assign` フィールド内のすべての変数の合計サイズも最大 256 KiB です。例えば、X と Y に 128 KiB を割り当てることはできますが、同じ `Assign` フィールドで X と Y の両方に 256 KiB を割り当てることはできません。

 1 回の実行で保存できるすべての変数の合計サイズは 10MiB を超えることはできません。

## JSONPath ステートでの変数の使用
<a name="using-variables-in-jsonpath-states"></a>

 変数は、クエリ言語に JSONPath を用いるステートでも使用できます。

 変数は、JSONPath 式 (`$.` または `$$.` 構文) を受け入れる任意のフィールドで参照できます。ただし、`ResultPath` フィールドは例外であり、これはステートの結果をステートの入力内のどこに挿入するかを指定します。変数は `ResultPath` では使用できません。

 JSONPath では、`$` 記号は「現在」の値を参照し、`$$` はステートの Context オブジェクトを表します。JSONPath 式は `$.customer.name` のように `$.` で始めることができます。`$$.Execution.Id` のように `$$.` を使用してコンテキストにアクセスできます。

 変数を参照するには、変数名の前に `$` 記号を付けて `$x` や `$order.numItems` のように記述します。

 組み込み関数を受け入れる **JSONPath** フィールドでは、引数で変数を使用できます (例: `States.Format('The order number is {}', $order.number)`)。

 次の図では、**JSONPath** タスクの Assign ステップが ResultSelector と同時に発生する方法を示しています。

 ![\[Logical diagram of a state that uses JSONPath query language.\]](http://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/images/vars-jsonpath.png)

 **JSONPath での変数割り当て**

 JSONPath での変数割り当てはペイロードテンプレートの動作と似ています。`.$` で終わるフィールドは JSONPath 式を表しており、Step Functions がステートマシンの実行時に値へと評価します (例: `$.order..product` や `$.order.total`)。

```
# Example of Assign with JSONPath
{
  "Type": "Task",
  ...
  "Assign": {
    "products.$": "$.order..product",
    "orderTotal.$": "$.order.total"
  },
  "Next": "the next state"
}
```

 JSONPath のステートでは、`Assign` フィールド内の `$` の値はステートタイプによって決まります。`Task,`、`Map`、`Parallel` ステートでは、`$` は API/サブワークフローの結果を指します。`Choice` および `Wait` ステートでは、`$` は `InputPath` 適用後のステートの入力、つまり*有効な入力*を指します。`Pass` では、`$` は、`Result` フィールドによって生成されたか、`InputPath`/`Parameters` フィールドによって生成されたかにかかわらず、結果を指します。

 次の JSONPath の例では、JSON オブジェクトを `details` 変数に割り当て、JSONPath 式 `$.result.code` の結果を `resultCode` に、JSONPath 式 `States.Format('Hello {}', $customer.name)` の結果を `message` に割り当てています。これが `Task` ステート内であれば、`$.order.items` および `$.result.code` 内の `$` は API の結果を指します。`startTime` 変数には、Context オブジェクト `$$.Execution.StartTime` から取得した値が割り当てられます。

```
"Assign": {
   "details": {
      "status": "SUCCESS",
      "lineItems.$": "$.order.items"
   },
   "resultCode.$": "$.result.code",
   "message.$": "States.Format('Hello {}', $customer.name)",
   "startTime.$": "$$.Execution.StartTime"
}
```