Bermigrasi dari Fungsi Langkah AWS ke Workflows

Untuk membantu Anda bersiap bermigrasi dari Amazon Web Services (AWS) Step Functions ke Alur Kerja di Google Cloud, halaman ini menjelaskan persamaan dan perbedaan utama antara kedua produk tersebut. Informasi ini dimaksudkan untuk membantu mereka yang sudah memahami Fungsi Langkah dapat menerapkan arsitektur serupa menggunakan Workflows.

Seperti Step Functions, Workflows adalah platform orkestrasi berbasis status yang terkelola sepenuhnya dan menjalankan layanan dalam urutan yang Anda tentukan: alur kerja. Alur kerja ini dapat menggabungkan layanan, termasuk layanan kustom yang dihosting di Cloud Run atau Cloud Functions, layanan Google Cloud seperti Cloud Vision AI dan BigQuery, serta API berbasis HTTP apa pun.

Perhatikan bahwa Step Functions Express Workflows adalah jenis alur kerja AWS Step Functions yang tidak dipertimbangkan di sini karena durasi Alur Kerja Ekspres dibatasi, dan eksekusi alur kerja tepat satu kali tidak didukung.

Hello world

Di Step Functions, mesin status adalah alur kerja, dan tugas adalah status dalam alur kerja yang mewakili satu unit kerja yang dijalankan oleh layanan AWS lain. Fungsi Langkah memerlukan setiap status untuk menentukan status berikutnya.

Di Workflows, serangkaian langkah menggunakan sintaksis Workflows menjelaskan tugas yang harus dijalankan. Workflows memperlakukan langkah seolah-olah berada dalam daftar yang diurutkan dan menjalankannya satu per satu hingga semua langkah berjalan.

Contoh "Halo Dunia" berikut menunjukkan penggunaan status di Fungsi Langkah dan langkah di Workflows:

Fungsi Langkah

  {
    "Comment": "Hello world example of Pass states in Amazon States Language",
    "StartAt": "Hello",
    "States": {
      "Hello": {
        "Type": "Pass",
        "Result": "Hello",
        "Next": "World"
      },
      "World": {
        "Type": "Pass",
        "Result": "World",
        "End": true
      }
    }
  }

YAML Alur Kerja

  ---
  # Hello world example of steps using Google Cloud Workflows syntax
  main:
      steps:
      - Hello:
          next: World
      - World:
          next: end
  ...

JSON Workflows

  {
    "main": {
      "steps": [
        {
          "Hello": {
            "next": "World"
          }
        },
        {
          "World": {
            "next": "end"
          }
        }
      ]
    }
  }

Ringkasan perbandingan

Bagian ini membandingkan kedua produk tersebut secara lebih mendetail.

Fungsi LangkahWorkflows
SintaksJSON (YAML dalam alat) YAML atau JSON
Alur kontrolTransisi antar-negara bagian Kontrol alur imeratif dengan langkah
PekerjaResource (ARN) Permintaan HTTP dan konektor
KeandalanTangkap/percobaan ulang Tangkap/percobaan ulang
KeparalelanDidukung Didukung
Data statusStatus diteruskan Variabel Workflows
AuthenticationIAM IAM
Pengalaman penggunaWorkflow Studio, CLI, SDK, IaC Konsol Google Cloud, CLI, SDK, IaC
Harga Harga Step Functions Harga alur kerja
Sintaksis

Step Functions terutama menggunakan JSON untuk menentukan fungsi dan tidak mendukung YAML secara langsung; namun, di AWS Toolkit untuk Visual Studio Code dan di AWS CloudFormation, Anda dapat menggunakan YAML untuk definisi Fungsi Langkah.

Anda dapat menjelaskan langkah-langkah Workflows menggunakan sintaksis Workflows, dan langkah-langkah tersebut dapat ditulis dalam YAML atau JSON. Sebagian besar alur kerja berupa YAML. Contoh di halaman ini menunjukkan manfaat YAML, termasuk kemudahan membaca dan menulis, dan dukungan komentar yang native. Untuk penjelasan detail tentang sintaksis Workflows, lihat Referensi sintaksis.

Alur kontrol

Baik alur kerja model Workflows maupun Fungsi Langkah merupakan serangkaian tugas: steps di Workflows dan status di Fungsi Langkah. Keduanya memungkinkan tugas untuk menunjukkan tugas mana yang akan dijalankan berikutnya dan mendukung kondisional seperti switch untuk memilih unit pekerjaan berikutnya berdasarkan status saat ini. Salah satu perbedaan utamanya adalah Fungsi Langkah memerlukan setiap status untuk menentukan status berikutnya, sedangkan Workflows menjalankan langkah-langkah sesuai urutan yang ditentukan (termasuk langkah alternatif berikutnya). Untuk mengetahui informasi selengkapnya, lihat Kondisi dan Langkah-langkah.

Pekerja

Kedua produk mengatur resource komputasi seperti fungsi, container, dan layanan web lainnya untuk menyelesaikan berbagai hal. Pada Step Functions, pekerja diidentifikasi oleh kolom Resource yang secara sintaksis merupakan URI. URI yang digunakan untuk mengidentifikasi resource pekerja ada dalam format Amazon Resource Name (ARN), dan pengguna tidak dapat langsung memanggil endpoint HTTP arbitrer.

Alur kerja dapat mengirim permintaan HTTP ke endpoint HTTP arbitrer dan mendapatkan respons. Konektor memudahkan Anda terhubung ke Google Cloud API lain dalam alur kerja, dan mengintegrasikan alur kerja Anda dengan produk Google Cloud lainnya seperti Pub/Sub, BigQuery, atau Cloud Build. Konektor menyederhanakan layanan panggilan karena menangani pemformatan permintaan untuk Anda, menyediakan metode dan argumen sehingga Anda tidak perlu mengetahui detail Google Cloud API. Anda juga dapat mengonfigurasi kebijakan waktu tunggu dan polling.

Keandalan

Jika tugas gagal, alur kerja Anda harus dapat mencoba ulang dengan tepat, menangkap pengecualian jika diperlukan, dan mengubah rute alur kerja sesuai kebutuhan. Baik Fungsi Langkah maupun Alur Kerja mencapai keandalan menggunakan mekanisme yang serupa: penangkapan pengecualian dengan percobaan ulang, dan akhirnya pengiriman ke tempat lain dalam alur kerja. Untuk mengetahui informasi selengkapnya, lihat Error alur kerja.

Keparalelan

Anda mungkin ingin alur kerja Anda mengatur beberapa tugas secara paralel. Step Function menyediakan dua cara untuk mencapai hal ini: Anda dapat mengambil satu item data dan meneruskannya secara paralel ke beberapa tugas yang berbeda; atau, Anda dapat menggunakan array dan meneruskan elemennya ke tugas yang sama.

Di Workflows, Anda dapat menentukan bagian alur kerja dengan dua langkah atau lebih dapat dijalankan secara serentak. Anda dapat menentukan cabang yang berjalan secara serentak, atau loop dengan iterasi berjalan secara serentak. Untuk mengetahui detailnya, lihat Menjalankan langkah-langkah alur kerja secara paralel.

Data status

Salah satu manfaat mesin alur kerja adalah data status dipertahankan untuk Anda tanpa datastore eksternal. Pada Step Functions, data status diteruskan dalam struktur JSON dari satu status ke status lainnya.

Di Workflows, Anda dapat menyimpan data status dalam variabel global. Karena Anda diizinkan untuk memiliki durasi eksekusi hingga satu tahun, Anda dapat menyimpan data status selama instance masih dalam eksekusi.

Authentication

Kedua produk ini mengandalkan sistem Identity and Access Management (IAM) yang mendasarinya untuk autentikasi dan kontrol akses. Misalnya, Anda dapat menggunakan peran IAM untuk memanggil Fungsi Langkah.

Di Workflows, Anda dapat menggunakan akun layanan untuk memanggil alur kerja; Anda dapat menggunakan OAuth 2.0 atau OIDC untuk terhubung dengan Google Cloud API, dan dapat menggunakan header permintaan otorisasi untuk melakukan autentikasi dengan API pihak ketiga. Untuk mengetahui informasi lebih lanjut, lihat bagian Memberikan izin alur kerja untuk mengakses resource Google Cloud dan Membuat permintaan terautentikasi dari alur kerja.

Pengalaman pengguna

Anda dapat menggunakan alat command line, atau Infrastructure as Code (IaC) seperti Terraform, untuk menentukan dan mengelola Fungsi Langkah dan Workflows.

Selain itu, Workflows mendukung eksekusi alur kerja menggunakan library klien, di Konsol Google Cloud, menggunakan Google Cloud CLI, atau dengan mengirim permintaan ke Workflows REST API. Untuk mengetahui detailnya, lihat Menjalankan alur kerja.

Harga

Kedua produk memiliki paket gratis. Untuk mengetahui detail selengkapnya, lihat halaman penetapan harga masing-masing: Harga Fungsi Langkah dan Harga alur kerja.

Memetakan jenis status ke langkah

Ada delapan jenis status dalam Fungsi Langkah. Status adalah elemen pada mesin status yang dapat membuat keputusan berdasarkan inputnya, melakukan tindakan, dan meneruskan output ke status lain. Sebelum bermigrasi dari Fungsi Langkah ke Alur kerja, pastikan Anda memahami cara menerjemahkan setiap jenis status menjadi langkah Workflows.

Choice

Status Choice menambahkan logika percabangan ke mesin status.

Di Workflows, Anda dapat menggunakan blok switch sebagai mekanisme pemilihan yang memungkinkan nilai ekspresi mengontrol alur eksekusi alur kerja. Jika ada nilai yang cocok, pernyataan kondisi tersebut akan dieksekusi. Untuk mengetahui informasi selengkapnya, lihat Kondisi.

Fungsi Langkah

  "ChoiceState": {
    "Type": "Choice",
    "Choices": [
      {
        "Variable": "$.foo",
        "NumericEquals": 1,
        "Next": "FirstMatchState"
      },
      {
        "Variable": "$.foo",
        "NumericEquals": 2,
        "Next": "SecondMatchState"
      }
    ],
    "Default": "DefaultState"
  }

YAML Alur Kerja

  switch:
    - condition: ${result.body.SomeField < 10}
      next: small
    - condition: ${result.body.SomeField < 100}
      next: medium
    - condition: true
      next: default_step

JSON Workflows

  {
    "switch": [
      {
        "condition": "${result.body.SomeField < 10}",
        "next": "small"
      },
      {
        "condition": "${result.body.SomeField < 100}",
        "next": "medium"
      },
      {
        "condition": true,
        "next": "default_step"
      }
    ]
  }

Fail

Status Fail menghentikan eksekusi mesin status dan menandainya sebagai kegagalan.

Di Workflows, Anda dapat melaporkan error kustom menggunakan sintaksis raise, dan Anda dapat menangkap serta menangani error menggunakan blok try/except. Untuk mengetahui informasi selengkapnya, lihat Melaporkan error.

Fungsi Langkah

  "FailState": {
      "Type": "Fail",
      "Error": "ErrorA",
      "Cause": "Kaiju attack"
  }

YAML Alur Kerja

  raise:
      code: 55
      message: "Something went wrong."

JSON Workflows

  {
    "raise": {
      "code": 55,
      "message": "Something went wrong."
    }
  }

Map

Status Map dapat digunakan untuk menjalankan serangkaian langkah bagi setiap elemen array input.

Di Workflows, Anda dapat menggunakan loop for untuk iterasi.

Fungsi Langkah

  { "StartAt": "ExampleMapState",
    "States": {
      "ExampleMapState": {
        "Type": "Map",
        "Iterator": {
           "StartAt": "CallLambda",
           "States": {
             "CallLambda": {
               "Type": "Task",
               "Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloFunction",
               "End": true
             }
           }
        }, "End": true
      }
    }
  }

YAML Alur Kerja

  - assignStep:
      assign:
        - map:
            1: 10
            2: 20
            3: 30
        - sum: 0
  - loopStep:
      for:
          value: key
          in: ${keys(map)}
          steps:
            - sumStep:
                assign:
                  - sum: ${sum + map[key]}
  - returnStep:
      return: ${sum}

JSON Workflows

  [
    {
      "assignStep": {
        "assign": [
          {
            "map": {
              "1": 10,
              "2": 20,
              "3": 30
            }
          },
          {
            "sum": 0
          }
        ]
      }
    },
    {
      "loopStep": {
        "for": {
          "value": "key",
          "in": "${keys(map)}",
          "steps": [
            {
              "sumStep": {
                "assign": [
                  {
                    "sum": "${sum + map[key]}"
                  }
                ]
              }
            }
          ]
        }
      }
    },
    {
      "returnStep": {
        "return": "${sum}"
      }
    }
  ]

Parallel

Status Parallel dapat digunakan untuk membuat cabang paralel eksekusi di mesin status Anda. Pada contoh Step Functions berikut, pencarian alamat dan telepon dilakukan secara paralel.

Di Workflows, Anda dapat menggunakan langkah parallel untuk menentukan bagian alur kerja dengan dua langkah atau lebih dapat dijalankan secara serentak. Untuk mengetahui informasi selengkapnya, lihat Langkah paralel.

Fungsi Langkah

  { "StartAt": "LookupCustomerInfo",
    "States": {
      "LookupCustomerInfo": {
        "Type": "Parallel",
        "End": true,
        "Branches": [
          {
           "StartAt": "LookupAddress",
           "States": {
             "LookupAddress": {
               "Type": "Task",
               "Resource": "arn:aws:lambda:us-east-1:123456789012:function:AddressFinder",
               "End": true
             }
           }
         },
         {
           "StartAt": "LookupPhone",
           "States": {
             "LookupPhone": {
               "Type": "Task",
               "Resource": "arn:aws:lambda:us-east-1:123456789012:function:PhoneFinder",
               "End": true
             }
           }
         }
        ]
      }
    }
  }

YAML Alur Kerja

  main:
     params: [args]
     steps:
     - init:
         assign:
         - workflow_id: "lookupAddress"
         - customer_to_lookup:
             - address: ${args.customerId}
             - phone: ${args.customerId}
         - addressed: ["", ""] # to write to this variable, you must share it
     - parallel_address:
         parallel:
             shared: [addressed]
             for:
                 in: ${customer_to_lookup}
                 index: i # optional, use if index is required
                 value: arg
                 steps:
                 - address:
                     call: googleapis.workflowexecutions.v1.projects.locations.workflows.executions.run
                     args:
                         workflow_id: ${workflow_id}
                         argument: ${arg}
                     result: r
                 - set_result:
                     assign:
                     - addressed[i]: ${r}
     - return:
             return: ${addressed}

JSON Workflows

  {
    "main": {
      "params": [
        "args"
      ],
      "steps": [
        {
          "init": {
            "assign": [
              {
                "workflow_id": "lookupAddress"
              },
              {
                "customer_to_lookup": [
                  {
                    "address": "${args.customerId}"
                  },
                  {
                    "phone": "${args.customerId}"
                  }
                ]
              },
              {
                "addressed": [
                  "",
                  ""
                ]
              }
            ]
          }
        },
        {
          "parallel_address": {
            "parallel": {
              "shared": [
                "addressed"
              ],
              "for": {
                "in": "${customer_to_lookup}",
                "index": "i",
                "value": "arg",
                "steps": [
                  {
                    "address": {
                      "call": "googleapis.workflowexecutions.v1.projects.locations.workflows.executions.run",
                      "args": {
                        "workflow_id": "${workflow_id}",
                        "argument": "${arg}"
                      },
                      "result": "r"
                    }
                  },
                  {
                    "set_result": {
                      "assign": [
                        {
                          "addressed[i]": "${r}"
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "return": {
            "return": "${addressed}"
          }
        }
      ]
    }
  }

Pass

Status Pass meneruskan inputnya ke output-nya, tanpa melakukan tugas. Atribut ini biasa digunakan untuk memanipulasi data status di JSON.

Karena Workflows tidak meneruskan data dengan cara ini, Anda dapat membiarkan status sebagai tanpa pengoperasian, atau Anda dapat menggunakan langkah penetapan untuk mengubah variabel. Untuk mengetahui informasi selengkapnya, lihat Menetapkan variabel.

Fungsi Langkah

  "No-op": {
    "Type": "Pass",
    "Result": {
      "x-datum": 0.38,
      "y-datum": 622.22
    },
    "ResultPath": "$.coords",
    "Next": "End"
  }

YAML Alur Kerja

  assign:
      - number: 5
      - number_plus_one: ${number+1}
      - other_number: 10
      - string: "hello"

JSON Workflows

  {
    "assign": [
      {
        "number": 5
      },
      {
        "number_plus_one": "${number+1}"
      },
      {
        "other_number": 10
      },
      {
        "string": "hello"
      }
    ]
  }

Berhasil

Status Succeed berhasil menghentikan eksekusi.

Di Workflows, Anda dapat menggunakan return di alur kerja utama untuk menghentikan eksekusi alur kerja. Anda juga dapat menyelesaikan alur kerja dengan menyelesaikan langkah terakhir (dengan asumsi bahwa langkah tersebut tidak melompat ke langkah lain), atau Anda dapat menggunakan next: end untuk menghentikan eksekusi alur kerja jika Anda tidak perlu menampilkan nilai. Untuk informasi selengkapnya, lihat Menyelesaikan eksekusi alur kerja.

Fungsi Langkah

  "SuccessState": {
    "Type": "Succeed"
  }

YAML Alur Kerja

  return: "Success!"
  next: end

JSON Workflows

  {
    "return": "Success!",
    "next": "end"
  }

Task

Status Task mewakili satu unit kerja yang dilakukan oleh mesin status. Pada contoh Fungsi Langkah berikut, fungsi ini memanggil fungsi Lambda. (Aktivitas adalah fitur AWS Step Functions yang memungkinkan Anda memiliki tugas di mesin status tempat pekerjaan dilakukan di tempat lain.)

Dalam contoh Workflows, panggilan dilakukan ke endpoint HTTP untuk memanggil Cloud Function. Anda juga dapat menggunakan konektor yang memudahkan akses ke produk Google Cloud lainnya. Selain itu, Anda dapat menjeda alur kerja dan melakukan polling untuk data. Atau, Anda dapat menggunakan endpoint callback untuk memberi tahu alur kerja bahwa peristiwa tertentu telah terjadi, dan menunggu peristiwa tersebut tanpa polling.

Fungsi Langkah

  "HelloWorld": {
    "Type": "Task",
    "Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloFunction",
    "End": true
  }

YAML Alur Kerja

  - HelloWorld:
      call: http.get
      args:
          url: https://REGION-PROJECT_ID.cloudfunctions.net/helloworld
      result: helloworld_result

JSON Workflows

  [
    {
      "HelloWorld": {
        "call": "http.get",
        "args": {
          "url": "https://REGION-PROJECT_ID.cloudfunctions.net/helloworld"
        },
        "result": "helloworld_result"
      }
    }
  ]

Wait

Status Wait menunda mesin status agar tidak dilanjutkan selama waktu tertentu.

Anda dapat menggunakan Workflows sys.sleep fungsi library standar untuk menangguhkan eksekusi selama jumlah detik yang ditentukan hingga maksimum 31536000 (satu tahun).

Fungsi Langkah

  "wait_ten_seconds" : {
    "Type" : "Wait",
    "Seconds" : 10,
    "Next": "NextState"
  }

YAML Alur Kerja

  - someSleep:
      call: sys.sleep
      args:
          seconds: 10

JSON Workflows

  [
    {
      "someSleep": {
        "call": "sys.sleep",
        "args": {
          "seconds": 10
        }
      }
    }
  ]

Contoh: Mengorkestrasi microservice

Contoh Fungsi Langkah berikut memeriksa harga saham, menentukan apakah akan membeli atau menjual, dan melaporkan hasilnya. Mesin status dalam contoh terintegrasi dengan AWS Lambda dengan meneruskan parameter, menggunakan antrean Amazon SQS untuk meminta persetujuan manusia, dan menggunakan topik Amazon SNS untuk menampilkan hasil kueri.

{
      "StartAt": "Check Stock Price",
      "Comment": "An example of integrating Lambda functions in Step Functions state machine",
      "States": {
          "Check Stock Price": {
              "Type": "Task",
              "Resource": "CHECK_STOCK_PRICE_LAMBDA_ARN",
              "Next": "Generate Buy/Sell recommendation"
          },
          "Generate Buy/Sell recommendation": {
              "Type": "Task",
              "Resource": "GENERATE_BUY_SELL_RECOMMENDATION_LAMBDA_ARN",
              "ResultPath": "$.recommended_type",
              "Next": "Request Human Approval"
          },
          "Request Human Approval": {
              "Type": "Task",
              "Resource": "arn:PARTITION:states:::sqs:sendMessage.waitForTaskToken",
              "Parameters": {
                  "QueueUrl": "REQUEST_HUMAN_APPROVAL_SQS_URL",
                  "MessageBody": {
                      "Input.$": "$",
                      "TaskToken.$": "$$.Task.Token"
                  }
              },
              "ResultPath": null,
              "Next": "Buy or Sell?"
          },
          "Buy or Sell?": {
              "Type": "Choice",
              "Choices": [
                  {
                      "Variable": "$.recommended_type",
                      "StringEquals": "buy",
                      "Next": "Buy Stock"
                  },
                  {
                      "Variable": "$.recommended_type",
                      "StringEquals": "sell",
                      "Next": "Sell Stock"
                  }
              ]
          },
          "Buy Stock": {
              "Type": "Task",
              "Resource": "BUY_STOCK_LAMBDA_ARN",
              "Next": "Report Result"
          },
          "Sell Stock": {
              "Type": "Task",
              "Resource": "SELL_STOCK_LAMBDA_ARN",
              "Next": "Report Result"
          },
          "Report Result": {
              "Type": "Task",
              "Resource": "arn:PARTITION:states:::sns:publish",
              "Parameters": {
                  "TopicArn": "REPORT_RESULT_SNS_TOPIC_ARN",
                  "Message": {
                      "Input.$": "$"
                  }
              },
              "End": true
          }
      }
  }

Bermigrasi ke Workflows

Untuk memigrasikan contoh Fungsi Langkah sebelumnya ke Workflows, Anda dapat membuat langkah Workflows yang setara dengan mengintegrasikan Cloud Functions, mendukung endpoint callback yang menunggu permintaan HTTP tiba di endpoint tersebut, dan menggunakan konektor Workflows untuk memublikasikan ke topik Pub/Sub sebagai pengganti topik Amazon SNS:

  1. Selesaikan langkah-langkah untuk membuat alur kerja, tetapi jangan men-deploy-nya terlebih dahulu.

  2. Pada definisi alur kerja, tambahkan satu langkah untuk membuat endpoint callback yang menunggu input manual, dan langkah yang menggunakan konektor Workflows untuk memublikasikan ke topik Pub/Sub. Contoh:

    YAML Alur Kerja

      ---
      main:
        steps:
          - init:
              assign:
                - projectId: '${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}'
                - region: LOCATION
                - topic: PUBSUB_TOPIC_NAME
          - Check Stock Price:
              call: http.get
              args:
                url: ${"https://" + region + "-" + projectId + ".cloudfunctions.net/CheckStockPrice"}
                auth:
                  type: OIDC
              result: stockPriceResponse
          - Generate Buy/Sell Recommendation:
              call: http.get
              args:
                url: ${"https://" + region + "-" + projectId + ".cloudfunctions.net/BuySellRecommend"}
                auth:
                  type: OIDC
                query:
                  price: ${stockPriceResponse.body.stock_price}
              result: recommendResponse
          - Create Approval Callback:
              call: events.create_callback_endpoint
              args:
                  http_callback_method: "GET"
              result: callback_details
          - Print Approval Callback Details:
              call: sys.log
              args:
                  severity: "INFO"
                  text: ${"Listening for callbacks on " + callback_details.url}
          - Await Approval Callback:
              call: events.await_callback
              args:
                  callback: ${callback_details}
                  timeout: 3600
              result: approvalResponse
          - Approval?:
              try:
                switch:
                  - condition: ${approvalResponse.http_request.query.response[0] == "yes"}
                    next: Buy or Sell?
              except:
                as: e
                steps:
                  - unknown_response:
                      raise: ${"Unknown response:" + e.message}
                      next: end
          - Buy or Sell?:
              switch:
                - condition: ${recommendResponse.body == "buy"}
                  next: Buy Stock
                - condition: ${recommendResponse.body == "sell"}
                  next: Sell Stock
                - condition: true
                  raise: ${"Unknown recommendation:" + recommendResponse.body}
          - Buy Stock:
              call: http.post
              args:
                url: ${"https://" + region + "-" + projectId + ".cloudfunctions.net/BuyStock"}
                auth:
                  type: OIDC
                body:
                  action: ${recommendResponse.body}
              result: message
          - Sell Stock:
              call: http.post
              args:
                url: ${"https://" + region + "-" + projectId + ".cloudfunctions.net/SellStock"}
                auth:
                  type: OIDC
                body:
                  action: ${recommendResponse.body}
              result: message
          - Report Result:
              call: googleapis.pubsub.v1.projects.topics.publish
              args:
                topic: ${"projects/" + projectId + "/topics/" + topic}
                body:
                  messages:
                  - data: '${base64.encode(json.encode(message))}'
              next: end
      ...

    JSON Workflows

      {
        "main": {
          "steps": [
            {
              "init": {
                "assign": [
                  {
                    "projectId": "${sys.get_env(\"GOOGLE_CLOUD_PROJECT_ID\")}"
                  },
                  {
                    "region": "LOCATION"
                  },
                  {
                    "topic": [
                      "PUBSUB_TOPIC_NAME"
                    ]
                  }
                ]
              }
            },
            {
              "Check Stock Price": {
                "call": "http.get",
                "args": {
                  "url": "${\"https://\" + region + \"-\" + projectId + \".cloudfunctions.net/CheckStockPrice\"}",
                  "auth": {
                    "type": "OIDC"
                  }
                },
                "result": "stockPriceResponse"
              }
            },
            {
              "Generate Buy/Sell Recommendation": {
                "call": "http.get",
                "args": {
                  "url": "${\"https://\" + region + \"-\" + projectId + \".cloudfunctions.net/BuySellRecommend\"}",
                  "auth": {
                    "type": "OIDC"
                  },
                  "query": {
                    "price": "${stockPriceResponse.body.stock_price}"
                  }
                },
                "result": "recommendResponse"
              }
            },
            {
              "Create Approval Callback": {
                "call": "events.create_callback_endpoint",
                "args": {
                  "http_callback_method": "GET"
                },
                "result": "callback_details"
              }
            },
            {
              "Print Approval Callback Details": {
                "call": "sys.log",
                "args": {
                  "severity": "INFO",
                  "text": "${\"Listening for callbacks on \" + callback_details.url}"
                }
              }
            },
            {
              "Await Approval Callback": {
                "call": "events.await_callback",
                "args": {
                  "callback": "${callback_details}",
                  "timeout": 3600
                },
                "result": "approvalResponse"
              }
            },
            {
              "Approval?": {
                "try": {
                  "switch": [
                    {
                      "condition": "${approvalResponse.http_request.query.response[0] == \"yes\"}",
                      "next": "Buy or Sell?"
                    }
                  ]
                },
                "except": {
                  "as": "e",
                  "steps": [
                    {
                      "unknown_response": {
                        "raise": "${\"Unknown response:\" + e.message}",
                        "next": "end"
                      }
                    }
                  ]
                }
              }
            },
            {
              "Buy or Sell?": {
                "switch": [
                  {
                    "condition": "${recommendResponse.body == \"buy\"}",
                    "next": "Buy Stock"
                  },
                  {
                    "condition": "${recommendResponse.body == \"sell\"}",
                    "next": "Sell Stock"
                  },
                  {
                    "condition": true,
                    "raise": "${\"Unknown recommendation:\" + recommendResponse.body}"
                  }
                ]
              }
            },
            {
              "Buy Stock": {
                "call": "http.post",
                "args": {
                  "url": "${\"https://\" + region + \"-\" + projectId + \".cloudfunctions.net/BuyStock\"}",
                  "auth": {
                    "type": "OIDC"
                  },
                  "body": {
                    "action": "${recommendResponse.body}"
                  }
                },
                "result": "message"
              }
            },
            {
              "Sell Stock": {
                "call": "http.post",
                "args": {
                  "url": "${\"https://\" + region + \"-\" + projectId + \".cloudfunctions.net/SellStock\"}",
                  "auth": {
                    "type": "OIDC"
                  },
                  "body": {
                    "action": "${recommendResponse.body}"
                  }
                },
                "result": "message"
              }
            },
            {
              "Report Result": {
                "call": "googleapis.pubsub.v1.projects.topics.publish",
                "args": {
                  "topic": "${\"projects/\" + projectId + \"/topics/\" + topic}",
                  "body": {
                    "messages": [
                      {
                        "data": "${base64.encode(json.encode(message))}"
                      }
                    ]
                  }
                },
                "next": "end"
              }
            }
          ]
        }
      }

    Ganti kode berikut:

    • LOCATION: region Google Cloud yang didukung. Misalnya, us-central1.
    • PUBSUB_TOPIC_NAME: nama topik Pub/Sub Anda. Contoh, my_stock_example.
  3. Deploy, lalu jalankan alur kerja.

  4. Selama eksekusi alur kerja, alur kerja akan dijeda dan menunggu Anda memanggil endpoint callback. Anda dapat menggunakan perintah curl untuk melakukannya. Contoh:

    curl -H "Authorization: Bearer $(gcloud auth print-access-token)"
    https://workflowexecutions.googleapis.com/v1/projects/CALLBACK_URL?response=yes
    

    Ganti CALLBACK_URL dengan bagian lain dari jalur ke endpoint callback Anda.

  5. Setelah alur kerja berhasil diselesaikan, Anda dapat menerima pesan dari langganan Pub/Sub. Contoh:

    gcloud pubsub subscriptions pull stock_example-sub  --format="value(message.data)" | jq
    

    Pesan output harus mirip dengan yang berikut ini (buy atau sell):

    {
      "body": "buy",
      "code": 200,
      "headers": {
      [...]
      }
    

Langkah selanjutnya