기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
Step Functions에서 JSONata로 데이터 트랜스포밍
JSONata를 사용하면 워크플로에서 데이터를 선택하고 트랜스포밍할 수 있는 강력한 오픈 소스 쿼리 및 표현식 언어를 얻을 수 있습니다. 간략한 소개와 전체 JSONata 참조는 JSONata.org 설명서
다음 동영상에서는 DynamoDB 예를 사용하여 Step Functions의 변수 및 JSONata를 설명합니다.
기존 워크플로에 JSONata 쿼리 및 트랜스포메이션 언어를 사용하려면 옵트인해야 합니다. 콘솔에서 워크플로를 생성할 때는 최상위 상태 머신 QueryLanguage에 대해 JSONata를 선택하는 것이 좋습니다. JSONPath를 사용하는 기존 또는 새 워크플로의 경우 콘솔은 개별 상태를 JSONata로 변환하는 옵션을 제공합니다.
JSONata를 선택하면 워크플로 필드가 5개의 JSONPath 필드(InputPath, Parameters, ResultSelector, ResultPath 및 OutputPath)에서 Arguments 및 Output 필드 2개로만 축소됩니다. 또한 JSON 객체 키 이름에는 .$를 사용하지 않습니다.
Step Functions를 처음 사용하는 경우 JSONata 표현식이 다음 구문을 사용함을 알기만 하면 됩니다.
JSONata 구문: "{% <JSONata expression> %}"
다음 코드 샘플은 JSONPath에서 JSONata로의 변환을 보여줍니다.
# Original sample using JSONPath
{
"QueryLanguage": "JSONPath", // Set explicitly; could be set and inherited from top-level
"Type": "Task",
...
"Parameters": {
"static": "Hello",
"title.$": "$.title",
"name.$": "$customerName", // With $customerName declared as a variable
"not-evaluated": "$customerName"
}
}
# Sample after conversion to JSONata
{
"QueryLanguage": "JSONata", // Set explicitly; could be set and inherited from top-level
"Type": "Task",
...
"Arguments": { // JSONata states do not have Parameters
"static": "Hello",
"title": "{% $states.input.title %}",
"name": "{% $customerName %}", // With $customerName declared as a variable
"not-evaluated": "$customerName"
}
}
"María"에 할당된 입력 { "title" : "Doctor" } 및 customerName 변수가 주어지면 두 상태 머신 모두 다음과 같은 JSON 결과를 생성합니다.
{
"static": "Hello",
"title": "Doctor",
"name": "María",
"not-evaluated": "$customerName"
}
다음 다이어그램에서는 JSONPath(왼쪽)를 JSONata(오른쪽)로 변환하여 상태 머신의 단계 복잡성을 줄이는 방법을 보여주는 그래픽 표현을 볼 수 있습니다.
상태 입력에서 Arguments로 데이터를 선택하고 트랜스포밍하여 통합 작업으로 전송할 수 있습니다(선택 사항). JSONata를 사용하면 변수에 할당하고 상태 Output에 대해 작업의 결과를 선택하고 트랜스포밍할 수 있습니다(선택 사항).
참고: Assign 및 Output 단계는 병렬로 발생합니다. 변수 할당 중에 데이터를 트랜스포밍하도록 선택하면 출력 단계에서 트랜스포밍된 데이터를 사용할 수 없습니다. 출력 단계에서 JSONata 트랜스포메이션을 다시 적용해야 합니다.
QueryLanguage 필드
워크플로 ASL 정의에는 상태 머신 정의의 최상위 수준과 개별 상태에 QueryLanguage 필드가 있습니다. 개별 상태 내에서 QueryLanguage를 설정하면 상태 머신을 한 번에 모두 업그레이드하는 대신 기존 상태 머신에서 JSONata를 점진적으로 채택할 수 있습니다.
QueryLanguage 필드는 "JSONPath" 또는 "JSONata"로 설정할 수도 있습니다. 최상위 QueryLanguage 필드를 생략하면 기본적으로 "JSONPath"로 설정됩니다. 상태에 상태 수준 QueryLanguage 필드가 포함된 경우 Step Functions는 해당 상태에 지정된 쿼리 언어를 사용합니다. 상태에 QueryLanguage 필드가 포함되지 않은 경우 최상위 QueryLanguage 필드에 지정된 쿼리 언어를 사용합니다.
JSON 문자열로 JSONata 표현식 작성
ASL 필드 값의 문자열, JSON 객체 필드 또는 JSON 배열 요소가 {% %} 문자로 묶이면 해당 문자열은 JSONata로 평가됩니다. 참고로 문자열은 선행 공백 없이 {%로 시작하고 후행 공백 없이 %}로 끝나야 합니다. 표현식을 잘못 열거나 닫으면 검증 오류가 발생합니다.
다음은 몇 가지 예제입니다.
-
"TimeoutSeconds" : "{% $timeout %}" -
Task상태의"Arguments" : {"field1" : "{% $name %}"} -
Map상태의"Items": [1, "{% $two %}", 3]
모든 ASL 필드가 JSONata를 허용하는 것은 아닙니다. 예를 들어 각 상태의 Type 필드는 상수 문자열로 설정해야 합니다. 마찬가지로 Task 상태 Resource 필드는 상수 문자열이어야 합니다. Map 상태 Items 필드는 배열 또는 객체로 평가되어야 하는 JSON 배열, JSON 객체 또는 JSONata 표현식을 수락합니다.
예약 변수: $states
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 상태:
-
$states.result는 성공할 경우 API 또는 하위 워크플로의 원시 결과를 참조합니다. -
$states.errorOutput는 API 또는 하위 워크플로가 실패한 경우 오류 출력을 참조합니다.$states.errorOutput은Catch필드의Assign또는Output에서 사용할 수 있습니다.
액세스할 수 없는 필드 및 상태에서 $states.result 또는 $states.errorOutput에 액세스하려는 시도는 상태 머신의 생성, 업데이트 또는 검증 시 포착됩니다.
$states.context 객체는 StartTime, 작업 토큰 및 초기 워크플로 입력과 같은 특정 실행에 대한 워크플로 정보를 제공합니다. 자세한 내용은 Step Functions의 컨텍스트 객체에서 실행 데이터 액세스 를 참조하세요.
표현식 오류 처리
런타임 시 JSONata 표현식 평가는 다음과 같은 다양한 이유로 실패할 수 있습니다.
-
유형 오류 -
$x또는$y가 숫자가 아니면{% $x + $y %}와 같은 표현식이 실패합니다. -
유형 비호환성 - 표현식은 필드가 허용하지 않는 유형으로 평가될 수 있습니다. 예를 들어
TimeoutSeconds필드에는 숫자 입력이 필요하므로$timeout가 문자열을 반환하면{% $timeout %}표현식이 실패합니다. -
범위를 벗어난 값 - 필드의 허용 범위를 벗어난 값을 생성하는 표현식은 실패합니다. 예를 들어
{% $evaluatesToNegativeNumber %}와 같은 표현식은TimeoutSeconds필드에서 실패합니다. -
결과 반환 실패 - JSON은 정의되지 않은 값 표현식을 나타낼 수 없으므로 표현식
{% $data.thisFieldDoesNotExist %}에 오류가 발생합니다.
각 경우 인터프리터에서 States.QueryEvaluationError 오류가 발생합니다. Task, Map 및 Parallel 상태는 오류를 포착하는 Catch 필드와 오류에 대해 재시도하는 Retry 필드를 제공할 수 있습니다.
JSONPath에서 JSONata로 변환
다음 섹션에서는 JSONPath와 JSONata로 작성된 코드의 차이점을 비교하고 설명합니다.
더 이상 경로 필드 없음
ASL을 사용하려면 개발자가 에서 TimeoutSecondsPath와 같이 필드의 Path 버전을 사용하여 JSONPath를 사용할 때 상태 데이터에서 값을 선택해야 합니다. JSONata를 사용하는 경우 ASL은 TimeoutSeconds와 같은 경로가 아닌 Path 필드에서 {% %}에 포함된 JSONata 표현식을 자동으로 해석하므로 더 이상 필드를 사용하지 않습니다.
-
JSONPath 레거시 예:
"TimeoutSecondsPath": "$timeout" -
JSONata:
"TimeoutSeconds": "{% $timeout %}"
마찬가지로 Map 상태는 JSON 배열, JSON 객체 또는 배열 또는 객체로 평가되어야 하는 JSONata 표현식을 허용하는 Items 필드로 대체ItemsPath되었습니다.
JSON 객체
ASL은 페이로드 템플릿이라는 용어를 사용하여 Parameters 및 ResultSelector 필드 값에 대한 JSONPath 표현식을 포함할 수 있는 JSON 객체를 설명합니다. JSONata 평가는 자체적으로 또는 JSON 객체나 JSON 배열 내에서 발생하는 모든 문자열에 대해 수행되므로 ASL은 JSONata에 대해 페이로드 템플릿이라는 용어를 사용하지 않습니다.
더 이상 .$ 없음
ASL에서는 JSONPath 및 내장 함수를 사용하려면 페이로드 템플릿의 필드 이름에 '.$'를 추가해야 합니다. "QueryLanguage":"JSONata"를 지정할 때 JSON 객체 필드 이름에 '.$' 규칙을 더 이상 사용하지 않습니다. 대신 JSONata 표현식을 {% %} 문자로 묶습니다. 객체가 다른 배열 또는 객체 내에 얼마나 깊이 중첩되는지에 관계없이 모든 문자열 값 필드에 동일한 규칙을 사용합니다.
Arguments 및 Output 필드
QueryLanguage를 JSONata로 설정하면 이전 I/O 처리 필드(InputPath, Parameters, ResultSelector, ResultPath 및 OutputPath)가 비활성화되고 대부분의 상태는 Arguments 및 Output이라는 2개의 새 필드를 가져옵니다.
JSONata는 JSONPath에 사용되는 필드에 비해 I/O 트랜스포메이션을 수행하는 더 간단한 방법을 제공합니다. JSONata의 기능은 JSONPath를 사용하는 이전 5개 필드보다 Arguments 및 Output을 더 효과적으로 만듭니다. 또한 이러한 새 필드 이름은 ASL을 단순화하고 값 전달 및 반환을 위한 모델을 명확히 하는 데 도움이 됩니다.
Arguments 및 Output 필드(및 Map 상태의 ItemSelector와 같은 기타 유사한 필드)는 다음과 같은 JSON 객체 중 하나를 허용합니다.
"Arguments": {
"field1": 42,
"field2": "{% jsonata expression %}"
}
또는 다음과 같이 JSONata 표현식을 직접 사용할 수 있습니다.
"Output": "{% jsonata expression %}"
출력은 "Output":true, "Output":42과 같은 모든 유형의 JSON 값도 수락할 수 있습니다.
Arguments 및 Output 필드는 JSONata만 지원하므로 JSONPath를 사용하는 워크플로에서 사용할 수 없습니다. 반대로 InputPath, Parameters, ResultSelector, ResultPath, OutputPath, 및 기타 JSONPath 필드는 JSONPath에서만 지원되므로 JSONata를 최상위 워크플로 또는 상태 쿼리 언어로 사용할 때는 경로 기반 필드를 사용할 수 없습니다.
Pass 상태
패스 상태의 선택적 결과는 이전에 가상 작업의 출력으로 처리되었습니다. 워크플로 또는 상태 쿼리 언어로 JSONata를 선택한 경우 이제 새 Output 필드를 사용할 수 있습니다.
Choice 상태
JSONPath를 사용하는 경우 Choice 상태에는 입력 Variable 및 다음 NumericLessThanEqualsPath와 같은 수많은 비교 경로가 있습니다.
# JSONPath choice state sample, with Variable and comparison path
"Check Price": {
"Type": "Choice",
"Default": "Pause",
"Choices": [
{
"Variable": "$.current_price.current_price",
"NumericLessThanEqualsPath": "$.desired_price",
"Next": "Send Notification"
} ],
}
JSONata의 경우 Choice 상태에는 JSONata 표현식을 사용할 수 있는 Condition이 있습니다.
# Choice state after JSONata conversion
"Check Price": {
"Type": "Choice",
"Default": "Pause"
"Choices": [
{
"Condition": "{% $current_price <= $states.input.desired_priced %}",
"Next": "Send Notification"
} ]
참고: 변수 및 비교 필드는 JSONPath에서만 사용할 수 있습니다. 조건은 JSONata에서만 사용할 수 있습니다.
JSONata 예
Workflow Studio에서 다음 예를 생성하여 JSONata를 실험할 수 있습니다. 상태 머신을 생성 및 실행하거나 Test 상태를 사용하여 데이터를 전달하고 상태 머신 정의를 수정할 수도 있습니다.
예: 입력 및 출력
이 예에서는 JSONata를 선택할 때 $states.input을 사용하여 상태 입력을 지정하고 Output 필드를 사용하여 상태 출력을 지정하는 방법을 보여줍니다.
{ "Comment": "Input and Output example using JSONata", "QueryLanguage": "JSONata", "StartAt": "Basic Input and Output", "States": { "Basic Input and Output": { "QueryLanguage": "JSONata", "Type": "Succeed", "Output": { "lastName": "{% 'Last=>' & $states.input.customer.lastName %}", "orderValue": "{% $states.input.order.total %}" } } } }
워크플로가 입력으로 다음을 사용하여 실행되는 경우:
{ "customer": { "firstName": "Martha", "lastName": "Rivera" }, "order": { "items": 7, "total": 27.91 } }
테스트 상태 또는 상태 머신 실행은 다음 JSON 출력을 반환합니다.
{
"lastName": "Last=>Rivera",
"orderValue": 27.91
}
예: JSONata로 필터링
JSONata 경로 연산자FilterDietProducts 상태를 테스트할 수 있습니다.
JSONata를 사용한 필터링을 위한 상태 머신 정의
{ "Comment": "Filter products using JSONata", "QueryLanguage": "JSONata", "StartAt": "FilterDietProducts", "States": { "FilterDietProducts": { "Type": "Pass", "Output": { "dietProducts": "{% $states.input.products[calories=0] %}" }, "End": true } } }
테스트용 샘플 입력
{ "products": [ { "calories": 140, "flavour": "Cola", "name": "Product-1" }, { "calories": 0, "flavour": "Cola", "name": "Product-2" }, { "calories": 160, "flavour": "Orange", "name": "Product-3" }, { "calories": 100, "flavour": "Orange", "name": "Product-4" }, { "calories": 0, "flavour": "Lime", "name": "Product-5" } ] }
상태 머신에서 단계 테스트의 출력
{ "dietProducts": [ { "calories": 0, "flavour": "Cola", "name": "Product-2" }, { "calories": 0, "flavour": "Lime", "name": "Product-5" } ] }
Step Functions에서 제공하는 JSONata 함수
JSONata에는 문자열, 숫자, 집계, 부울, 배열, 객체, 날짜/시간 및 고차 함수에 대한 함수 라이브러리가 포함되어 있습니다. Step Functions는 JSONata 표현식에 사용할 수 있는 추가 JSONata 함수를 제공합니다. 이러한 내장 함수는 Step Functions 내장 함수를 대체하는 역할을 합니다. 내장 함수는 JSONPath 쿼리 언어를 사용하는 상태에서만 사용할 수 있습니다.
참고: 파라미터로 정수 값이 필요한 기본 제공 JSONata 함수는 제공된 정수가 아닌 숫자를 자동으로 반올림합니다.
$partition - 대형 배열을 분할하는 States.ArrayPartition 내장 함수와 동일한 JSONata입니다.
첫 번째 파라미터는 분할할 배열이고, 두 번째 파라미터는 청크 크기를 나타내는 정수입니다. 반환 값은 2차원 배열입니다. 인터프리터는 입력 배열을 청크 크기로 지정된 크기의 여러 배열로 청크합니다. 배열에 남아 있는 항목 수가 청크 크기보다 작으면 마지막 배열 청크 길이가 이전 배열 청크 길이보다 짧을 수 있습니다.
"Assign": {
"arrayPartition": "{% $partition([1,2,3,4], $states.input.chunkSize) %}"
}
$range - 값 배열을 생성하기 위한 States.ArrayRange 내장 함수와 동일한 JSONata입니다.
이 함수는 인수 3개를 사용합니다. 첫 번째 인수는 새 배열의 첫 번째 요소를 나타내는 정수이고, 두 번째 인수는 새 배열의 마지막 요소를 나타내는 정수입니다. 세 번째 인수는 새 배열의 요소를 위한 델타 값 정수입니다. 반환 값은 함수의 첫 번째 인수부터 델타로 조정된 사이에 요소가 있는 함수의 두 번째 인수까지 새로 생성된 값 배열입니다. 델타 값은 양수 또는 음수일 수 있으며, 종료 값에 도달하거나 초과할 때까지 마지막에서 각 요소를 늘리거나 줄일 수 있습니다.
"Assign": {
"arrayRange": "{% $range(0, 10, 2) %}"
}
$hash - States.Hash 내장 함수와 동일한 JSONata 사용하여 지정된 입력의 해시 값을 계산할 수 있습니다.
이 함수는 인수 2개를 사용합니다. 첫 번째 인수는 해싱할 소스 문자열입니다. 두 번째 인수는 해시 계산을 위해 해싱 알고리즘을 나타내는 문자열입니다. 해싱 알고리즘은 "MD5", "SHA-1", "SHA-256", "SHA-384", "SHA-512" 값 중 하나여야 합니다. 반환 값은 데이터의 계산된 해시의 문자열입니다.
이 함수는 JSONata가 기본적으로 해시 계산 기능을 지원하지 않기 때문에 생성되었습니다.
"Assign": {
"myHash": "{% $hash($states.input.content, $hashAlgorithmName) %}"
}
$random - 0 ≤ n < 1에서 난수 n을 반환하는 States.MathRandom 내장 함수와 동일한 JSONata입니다.
함수는 임의 함수의 시드 값을 나타내는 선택적 정수 인수를 사용합니다. 이 함수를 동일한 시드 값과 함께 사용하면 같은 숫자가 반환됩니다.
오버로드된 이 함수 $random
"Assign": {
"randNoSeed": "{% $random() %}",
"randSeeded": "{% $random($states.input.seed) %}"
}
$uuid - States.UUID 내장 함수의 JSONata 버전입니다.
함수에는 인수가 필요하지 않습니다. 이 함수는 v4 UUID를 반환합니다.
이 함수는 JSONata가 UUID 생성 기능을 기본적으로 지원하지 않기 때문에 생성되었습니다.
"Assign": {
"uniqueId": "{% $uuid() %}"
}
$parse - JSON 문자열을 역직렬화하는 JSONata 함수입니다.
함수는 문자열화된 JSON을 유일한 인수로 사용합니다.
JSONata는 $eval을 통해 이 기능을 지원하지만 Step Functions 워크플로에서 $eval은 지원되지 않습니다.
"Assign": {
"deserializedPayload": "{% $parse($states.input.json_string) %}"
}