Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Mengubah data dengan Jsonata di Step Functions
Dengan Jsonata, Anda mendapatkan kueri open source dan bahasa ekspresi yang kuat untuk memilih dan mengubah data dalam alur kerja Anda. Untuk pengantar singkat dan referensi Jsonata lengkap, lihat JSONata.org dokumentasi.
Versi Jsonata yang didukung
Step Functions mendukung Jsonata versi 2.0.6.
Video berikut menjelaskan variabel dan Jsonata dalam Step Functions dengan contoh DynamoDB:
Anda harus memilih untuk menggunakan kueri Jsonata dan bahasa transformasi untuk alur kerja yang ada. Saat membuat alur kerja di konsol, sebaiknya pilih Jsonata untuk mesin status tingkat atas. QueryLanguage Untuk alur kerja yang ada atau baru yang menggunakan JsonPath, konsol menyediakan opsi untuk mengonversi status individual ke Jsonata.
Setelah memilih Jsonata, bidang alur kerja Anda akan dikurangi dari lima bidang JsonPath (InputPath,,, Parameters ResultSelectorResultPath, danOutputPath) menjadi hanya dua bidang: dan. Arguments Output Juga, Anda tidak akan menggunakan .$ pada nama kunci objek JSON.
Jika Anda baru mengenal Step Functions, Anda hanya perlu tahu bahwa ekspresi Jsonata menggunakan sintaks berikut:
Sintaks Jsonata: "{% <JSONata expression> %}"
Contoh kode berikut menunjukkan konversi dari JsonPath ke 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"
}
}
Diberikan input { "title" : "Doctor" } dan variabel yang customerName ditugaskan ke"María", kedua mesin status akan menghasilkan hasil JSON berikut:
{
"static": "Hello",
"title": "Doctor",
"name": "María",
"not-evaluated": "$customerName"
}
Pada diagram berikutnya, Anda dapat melihat representasi grafis yang menunjukkan bagaimana mengonversi JsonPath (kiri) ke Jsonata (kanan) akan mengurangi kompleksitas langkah-langkah di mesin status Anda:
Anda dapat (opsional) memilih dan mengubah data dari input status menjadi Argumen untuk dikirim ke tindakan terintegrasi Anda. Dengan Jsonata, Anda kemudian dapat (opsional) memilih dan mengubah hasil dari tindakan untuk menetapkan ke variabel dan untuk Output status.
Catatan: Langkah penetapan dan Output terjadi secara paralel. Jika Anda memilih untuk mengubah data selama penetapan variabel, data yang diubah itu tidak akan tersedia di langkah Output. Anda harus menerapkan kembali transformasi Jsonata di langkah Output.
QueryLanguage lapangan
Dalam definisi ASL alur kerja Anda, ada QueryLanguage bidang di tingkat atas definisi mesin negara dan di masing-masing negara bagian. Dengan menyetel QueryLanguage di dalam masing-masing status, Anda dapat secara bertahap mengadopsi Jsonata di mesin status yang ada daripada memutakhirkan mesin status sekaligus.
QueryLanguageBidang dapat diatur ke "JSONPath" atau"JSONata". Jika QueryLanguage bidang tingkat atas dihilangkan, defaultnya adalah. "JSONPath" Jika status berisi QueryLanguage bidang tingkat status, Step Functions akan menggunakan bahasa kueri yang ditentukan untuk status tersebut. Jika negara tidak berisi QueryLanguage bidang, maka itu akan menggunakan bahasa kueri yang ditentukan di QueryLanguage bidang tingkat atas.
Menulis ekspresi JSONata dalam string JSON
Ketika string dalam nilai bidang ASL, bidang objek JSON, atau elemen array JSON dikelilingi oleh {% %} karakter, string itu akan dievaluasi sebagai Jsonata. Catatan, string harus dimulai {% dengan tanpa spasi utama, dan harus %} diakhiri tanpa spasi tambahan. Membuka atau menutup ekspresi dengan tidak benar akan menghasilkan kesalahan validasi.
Beberapa contoh:
-
"TimeoutSeconds" : "{% $timeout %}" -
"Arguments" : {"field1" : "{% $name %}"}dalam suatuTasknegara -
"Items": [1, "{% $two %}", 3]dalam suatuMapnegara
Tidak semua bidang ASL menerima Jsonata. Misalnya, setiap Type bidang status harus disetel ke string konstan. Demikian pula, Resource bidang Task negara harus berupa string konstan. ItemsBidang Map status akan menerima array JSON, objek JSON, atau ekspresi JSONata yang harus mengevaluasi ke array atau objek.
Variabel yang dicadangkan: $ negara
Step Functions mendefinisikan variabel cadangan tunggal yang disebut $states. Dalam status Jsonata, struktur berikut ditetapkan $states untuk digunakan dalam ekspresi 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
}
Pada entri status, Step Functions menetapkan masukan status ke $states.input. Nilai $states.input dapat digunakan di semua bidang yang menerima ekspresi Jsonata. $states.inputselalu mengacu pada input status asli.
UntukTask,Parallel, dan Map menyatakan:
-
$states.resultmengacu pada hasil mentah API atau sub-alur kerja jika berhasil. -
$states.errorOutputmengacu pada Output Kesalahan jika API atau sub-alur kerja gagal.$states.errorOutputdapat digunakan diCatchlapanganAssignatauOutput.
Mencoba mengakses $states.result atau $states.errorOutput di bidang dan status di mana mereka tidak dapat diakses akan tertangkap saat pembuatan, pembaruan, atau validasi mesin status.
$states.contextObjek memberikan informasi alur kerja Anda tentang eksekusi spesifik mereka, seperti, token tugasStartTime, dan input alur kerja awal. Untuk mempelajari lebih lanjut, lihatMengakses data eksekusi dari objek Context di Step Functions.
Menangani kesalahan ekspresi
Saat runtime, evaluasi ekspresi Jsonata mungkin gagal karena berbagai alasan, seperti:
-
Jenis kesalahan - Ekspresi, seperti
{% $x + $y %}, akan gagal jika$xatau$ybukan angka. -
Ketidakcocokan tipe - Ekspresi mungkin mengevaluasi tipe yang tidak akan diterima bidang. Misalnya, bidang
TimeoutSecondsmembutuhkan input numerik, sehingga ekspresi{% $timeout %}akan gagal jika$timeoutmengembalikan string. -
Nilai di luar jangkauan - Ekspresi yang menghasilkan nilai yang berada di luar rentang yang dapat diterima untuk bidang akan gagal. Misalnya, ekspresi seperti
{% $evaluatesToNegativeNumber %}akan gagal diTimeoutSecondslapangan. -
Kegagalan untuk mengembalikan hasil - JSON tidak dapat mewakili ekspresi nilai yang tidak ditentukan, sehingga ekspresi
{% $data.thisFieldDoesNotExist %}akan menghasilkan kesalahan. -
Batas memori terlampaui - Ekspresi Jsonata yang mengkonsumsi terlalu banyak memori selama evaluasi akan gagal dengan kesalahan.
Expression evaluation memory limit exceededHal ini dapat terjadi dengan ekspresi yang memproses atau mengubah sejumlah besar data. Untuk mengatasi batasan ini, pertimbangkan untuk memindahkan transformasi data ke fungsi Lambda. -
Expression timeout - Ekspresi Jsonata yang membutuhkan waktu lebih dari 1 detik untuk mengevaluasi akan gagal dengan kesalahan.
Expression evaluation timeoutIni dapat terjadi dengan ekspresi yang berisi loop tak terbatas atau operasi yang sangat mahal. -
Stack overflow - Ekspresi Jsonata yang melebihi kedalaman rekursi maksimum akan gagal dengan file.
Stack overflow errorJika rekursi tidak berakhir, pastikan fungsi memiliki kasus dasar atau kondisi terminasi yang benar. Jika rekursi berakhir tetapi tumpukan panggilan tumbuh terlalu dalam, pertimbangkan untuk menulis ulang fungsi sebagai rekursif ekor untuk mengurangi kedalaman tumpukan.
Dalam setiap kasus, penerjemah akan melempar kesalahan:States.QueryEvaluationError. Status Tugas, Peta, dan Paralel Anda dapat menyediakan Catch bidang untuk menangkap kesalahan, dan Retry bidang untuk mencoba lagi kesalahan tersebut.
Mengonversi dari JsonPath ke Jsonata
Bagian berikut membandingkan dan menjelaskan perbedaan antara kode yang ditulis dengan JsonPath dan Jsonata.
Tidak ada lagi bidang jalur
ASL mengharuskan pengembang menggunakan Path versi bidang, seperti dalamTimeoutSecondsPath, untuk memilih nilai dari data status saat menggunakan JsonPath. Saat Anda menggunakan Jsonata, Anda tidak lagi menggunakan Path bidang karena ASL akan menafsirkan ekspresi Jsonata {% %} -tertutup secara otomatis untuk Anda di bidang non-Path, seperti. TimeoutSeconds
-
Contoh warisan JsonPath:
"TimeoutSecondsPath": "$timeout" -
Jsonata:
"TimeoutSeconds": "{% $timeout %}"
Demikian pula, Map keadaan ItemsPath telah diganti dengan Items bidang yang menerima array JSON, objek JSON, atau ekspresi JSONata yang harus mengevaluasi ke array atau objek.
Objek JSON
ASL menggunakan istilah template payload untuk menggambarkan objek JSON yang dapat berisi ekspresi JSONPath untuk dan nilai bidang. Parameters ResultSelector ASL tidak akan menggunakan istilah template payload untuk Jsonata karena evaluasi Jsonata terjadi untuk semua string apakah itu terjadi sendiri atau di dalam objek JSON atau array JSON.
Tidak ada lagi. $
ASL mengharuskan Anda untuk menambahkan '.$' ke nama bidang di template payload untuk menggunakan JsonPath dan Fungsi Intrinsik. Saat Anda menentukan"QueryLanguage":"JSONata", Anda tidak lagi menggunakan konvensi '.$' untuk nama bidang objek JSON. Sebagai gantinya, Anda melampirkan ekspresi Jsonata dalam karakter. {% %} Anda menggunakan konvensi yang sama untuk semua bidang bernilai string, terlepas dari seberapa dalam objek tersebut bersarang di dalam array atau objek lain.
Argumen dan Bidang Output
Ketika QueryLanguage diatur keJSONata, bidang I/O pemrosesan lama akan dinonaktifkan (InputPath,, ParametersResultSelector, ResultPath danOutputPath) dan sebagian besar negara bagian akan mendapatkan dua bidang baru: Arguments danOutput.
Jsonata menyediakan cara yang lebih sederhana untuk melakukan I/O transformasi dibandingkan dengan bidang yang digunakan dengan JsonPath. Fitur Jsonata membuat Arguments dan Output lebih mampu daripada lima bidang sebelumnya dengan JsonPath. Nama bidang baru ini juga membantu menyederhanakan ASL Anda dan memperjelas model untuk meneruskan dan mengembalikan nilai.
OutputBidang Arguments and (dan bidang serupa lainnya seperti Map stateItemSelector) akan menerima objek JSON seperti:
"Arguments": {
"field1": 42,
"field2": "{% jsonata expression %}"
}
Atau, Anda dapat menggunakan ekspresi Jsonata secara langsung, misalnya:
"Output": "{% jsonata expression %}"
Output juga dapat menerima semua jenis nilai JSON juga, misalnya:"Output":true,"Output":42.
OutputBidang Arguments and hanya mendukung Jsonata, jadi tidak valid untuk menggunakannya dengan alur kerja yang menggunakan JsonPath. Sebaliknya,,,InputPath, Parameters ResultSelector ResultPathOutputPath, dan bidang JsonPath lainnya hanya didukung di JsonPath, jadi tidak valid untuk menggunakan bidang berbasis jalur saat menggunakan Jsonata sebagai alur kerja tingkat atas atau bahasa kueri status Anda.
Status Lulus
Hasil opsional dalam status Pass sebelumnya diperlakukan sebagai output dari tugas virtual. Dengan Jsonata dipilih sebagai alur kerja atau bahasa kueri status, Anda sekarang dapat menggunakan bidang Output baru.
Negara pilihan
Saat menggunakan JsonPath, status pilihan memiliki input Variable dan banyak jalur perbandingan, seperti berikut ini: 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"
} ],
}
Dengan Jsonata, status pilihan memiliki Condition tempat Anda dapat menggunakan ekspresi Jsonata:
# Choice state after JSONata conversion
"Check Price": {
"Type": "Choice",
"Default": "Pause"
"Choices": [
{
"Condition": "{% $current_price <= $states.input.desired_priced %}",
"Next": "Send Notification"
} ]
Catatan: Variabel dan bidang perbandingan hanya tersedia untuk JsonPath. Kondisi hanya tersedia untuk Jsonata.
Contoh Jsonata
Contoh berikut dapat dibuat di Workflow Studio untuk bereksperimen dengan Jsonata. Anda dapat membuat dan menjalankan mesin status, atau menggunakan status Uji untuk meneruskan data dan bahkan memodifikasi definisi mesin status.
Contoh: Input dan Output
Contoh ini menunjukkan $states.input cara menggunakan input status dan Output bidang untuk menentukan output status saat Anda memilih Jsonata.
{ "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 %}" } } } }
Ketika alur kerja dijalankan dengan berikut sebagai input:
{ "customer": { "firstName": "Martha", "lastName": "Rivera" }, "order": { "items": 7, "total": 27.91 } }
Uji status atau eksekusi mesin status akan mengembalikan output JSON berikut:
{
"lastName": "Last=>Rivera",
"orderValue": 27.91
}
Contoh: Memfilter dengan Jsonata
Anda dapat memfilter data Anda dengan operator JalurFilterDietProducts status dengan input sampel berikut.
Definisi mesin negara untuk pemfilteran dengan Jsonata
{ "Comment": "Filter products using JSONata", "QueryLanguage": "JSONata", "StartAt": "FilterDietProducts", "States": { "FilterDietProducts": { "Type": "Pass", "Output": { "dietProducts": "{% $states.input.products[calories=0] %}" }, "End": true } } }
Masukan sampel untuk pengujian
{ "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" } ] }
Keluaran dari pengujian langkah di mesin negara Anda
{ "dietProducts": [ { "calories": 0, "flavour": "Cola", "name": "Product-2" }, { "calories": 0, "flavour": "Lime", "name": "Product-5" } ] }
Contoh: Menggunakan output status sebelumnya dalam status Peta
Contoh ini menunjukkan cara menggunakan output dari status sebelumnya sebagai masukan untuk status Peta dengan Jsonata. Alur kerja berikut menggunakan status Pass untuk mensimulasikan tugas yang mengembalikan pesanan dengan daftar item, dan kemudian status Peta memilih array item dari output itu dan mengulang di atasnya.
Definisi mesin negara
{ "Comment": "Example: Using previous state output in a Map state with JSONata", "QueryLanguage": "JSONata", "StartAt": "GetOrder", "States": { "GetOrder": { "Type": "Pass", "Output": { "orderId": "{% $states.input.orderId %}", "items": "{% $states.input.items %}" }, "Next": "ProcessItems" }, "ProcessItems": { "Type": "Map", "Items": "{% $states.input.items %}", "ItemProcessor": { "ProcessorConfig": { "Mode": "INLINE" }, "StartAt": "CalculateItemTotal", "States": { "CalculateItemTotal": { "Type": "Pass", "Output": { "name": "{% $states.input.name %}", "total": "{% $states.input.price * $states.input.quantity %}" }, "End": true } } }, "End": true } } }
Dalam definisi ini, GetOrder status mengeluarkan data pesanan tidak berubah. Status ProcessItems Peta menggunakan "Items": "{% $states.input.items %}" untuk memilih items array dari outputGetOrder. Setiap iterasi menerima satu item dari array dan menghitung total item dengan mengalikan harga dengan kuantitas.
Masukan sampel
{ "orderId": "ORD-1234", "items": [ { "name": "Widget", "price": 4.99, "quantity": 3 }, { "name": "Gadget", "price": 12.50, "quantity": 2 }, { "name": "Bolt", "price": 0.75, "quantity": 10 } ] }
Output yang diharapkan
[
{
"name": "Widget",
"total": 14.97
},
{
"name": "Gadget",
"total": 25
},
{
"name": "Bolt",
"total": 7.5
}
]
Contoh: Meratakan output status Paralel
Bila Anda menggunakan keadaan Paralel, ia mengembalikan array di mana setiap elemen adalah output dari satu cabang. Dengan Jsonata, Anda dapat menggunakan Output bidang pada status Paralel untuk meratakan atau menggabungkan hasil ini menjadi satu objek. Pendekatan ini menggantikan bidang JsonPathResultSelector.
Contoh berikut menggunakan keadaan Paralel dengan dua cabang. Setiap cabang mensimulasikan panggilan GetItem DynamoDB dengan menggunakan status Pass. Keadaan Paralel menggunakan $merge($states.result) di Output bidangnya untuk menggabungkan hasil cabang menjadi satu objek.
Definisi mesin negara
{ "Comment": "Example: Flattening Parallel state output with JSONata", "QueryLanguage": "JSONata", "StartAt": "GetOrderAndCustomer", "States": { "GetOrderAndCustomer": { "Type": "Parallel", "Output": "{% $merge($states.result) %}", "Branches": [ { "StartAt": "Get Order", "States": { "Get Order": { "Type": "Pass", "Output": { "orderId": "{% $states.input.orderId %}", "orderDate": "2024-11-20", "total": 35.99 }, "End": true } } }, { "StartAt": "Get Customer", "States": { "Get Customer": { "Type": "Pass", "Output": { "customerId": "{% $states.input.customerId %}", "customerName": "Martha Rivera", "email": "martha@example.com" }, "End": true } } } ], "Next": "Done" }, "Done": { "Type": "Succeed" } } }
Masukan sampel
{ "orderId": "12345", "customerId": "C-100" }
Output yang diharapkan
{
"orderId": "12345",
"orderDate": "2024-11-20",
"total": 35.99,
"customerId": "C-100",
"customerName": "Martha Rivera",
"email": "martha@example.com"
}
$merge()Fungsi ini menggabungkan array objek menjadi satu objek. Jika cabang mengembalikan objek dengan kunci yang tumpang tindih, elemen array selanjutnya diutamakan. Hasil cabang diurutkan secara konsisten — mereka sesuai dengan urutan Branches array dalam definisi mesin status.
Fungsi JSONata disediakan oleh Step Functions
JSONata berisi pustaka fungsi untuk fungsi String, Numeric, Aggregation, Boolean, Array, Object, Date/Time dan High Order. Step Functions menyediakan fungsi Jsonata tambahan yang dapat Anda gunakan dalam ekspresi Jsonata Anda. Fungsi bawaan ini berfungsi sebagai pengganti fungsi intrinsik Step Functions. Fungsi intrinsik hanya tersedia di negara bagian yang menggunakan bahasa kueri JSONPath.
Catatan: Fungsi Built-in Jsonata yang memerlukan nilai integer sebagai parameter akan secara otomatis membulatkan nomor non-integer yang disediakan.
$partition - Jsonata setara dengan fungsi States.ArrayPartition intrinsik untuk partisi array besar.
Parameter pertama adalah array untuk partisi, parameter kedua adalah integer yang mewakili ukuran potongan. Nilai kembali akan menjadi array dua dimensi. Interpreter memotong array input menjadi beberapa array dari ukuran yang ditentukan oleh ukuran chunk. Panjang potongan array terakhir mungkin kurang dari panjang potongan array sebelumnya jika jumlah item yang tersisa dalam array lebih kecil dari ukuran potongan.
"Assign": {
"arrayPartition": "{% $partition([1,2,3,4], $states.input.chunkSize) %}"
}
$range - Jsonata setara dengan fungsi States.ArrayRange intrinsik untuk menghasilkan array nilai.
Fungsi ini membutuhkan tiga argumen. Argumen pertama adalah integer yang mewakili elemen pertama dari array baru, argumen kedua adalah integer yang mewakili elemen akhir dari array baru, dan argumen ketiga adalah bilangan bulat nilai delta untuk elemen dalam array baru. Nilai kembali adalah larik nilai yang baru dihasilkan mulai dari argumen pertama fungsi hingga argumen kedua fungsi dengan elemen di antaranya disesuaikan dengan delta. Nilai delta bisa positif atau negatif yang akan menambah atau mengurangi setiap elemen dari yang terakhir sampai nilai akhir tercapai atau terlampaui.
"Assign": {
"arrayRange": "{% $range(0, 10, 2) %}"
}
$hash - Jsonata setara dengan fungsi States.Hash intrinsik untuk menghitung nilai hash dari input yang diberikan.
Fungsi ini membutuhkan dua argumen. Argumen pertama adalah string sumber yang akan di-hash. Argumen kedua adalah string yang mewakili algoritma hashing untuk perhitungan hash. Algoritma hashing harus menjadi salah satu dari nilai berikut:"MD5",,"SHA-1", "SHA-256""SHA-384","SHA-512". Nilai kembali adalah string dari hash yang dihitung dari data.
Fungsi ini dibuat karena Jsonata tidak secara native mendukung kemampuan untuk menghitung hash.
"Assign": {
"myHash": "{% $hash($states.input.content, $hashAlgorithmName) %}"
}
$random - Jsonata setara dengan fungsi States.MathRandom intrinsik untuk mengembalikan angka acak n dimana. 0 ≤ n < 1
Fungsi ini mengambil argumen integer opsional yang mewakili nilai seed dari fungsi acak. Jika Anda menggunakan fungsi ini dengan nilai seed yang sama, ia mengembalikan angka yang identik.
Fungsi kelebihan beban ini dibuat karena fungsi Jsonata bawaan $random
"Assign": {
"randNoSeed": "{% $random() %}",
"randSeeded": "{% $random($states.input.seed) %}"
}
$uuid - versi Jsonata dari fungsi intrinsik. States.UUID
Fungsi ini tidak membutuhkan argumen. Fungsi ini mengembalikan UUID v4.
Fungsi ini dibuat karena Jsonata tidak secara native mendukung kemampuan untuk menghasilkan UUID.
"Assign": {
"uniqueId": "{% $uuid() %}"
}
$parse - fungsi Jsonata untuk deserialisasi string JSON.
Fungsi ini mengambil JSON stringified sebagai satu-satunya argumen.
Jsonata mendukung fungsi ini melalui$eval; namun, tidak didukung dalam $eval alur kerja Step Functions.
"Assign": {
"deserializedPayload": "{% $parse($states.input.json_string) %}"
}