Callback memungkinkan eksekusi alur kerja menunggu layanan lain membuat permintaan ke endpoint callback; permintaan tersebut melanjutkan eksekusi alur kerja.
Dengan callback, Anda dapat memberi tahu alur kerja bahwa peristiwa tertentu telah terjadi, dan menunggu peristiwa tersebut tanpa polling. Misalnya, Anda dapat membuat alur kerja yang memberi tahu Anda saat produk kembali tersedia atau saat item telah dikirim; atau yang menunggu untuk memungkinkan interaksi manusia seperti meninjau pesanan atau memvalidasi terjemahan.
Halaman ini menunjukkan cara membuat alur kerja yang mendukung endpoint callback, dan yang menunggu permintaan HTTP dari proses eksternal tiba di endpoint tersebut. Anda juga dapat menunggu peristiwa menggunakan callback dan pemicu Eventarc.
Callback memerlukan penggunaan dua fungsi bawaan library standar:
events.create_callback_endpoint
—Membuat endpoint callback yang mengharapkan metode HTTP yang ditentukanevents.await_callback
—Menunggu callback diterima di endpoint yang ditentukan
Membuat endpoint yang menerima permintaan callback
Buat endpoint callback yang dapat menerima permintaan HTTP untuk tiba di endpoint tersebut.
- Ikuti langkah-langkah untuk membuat alur kerja baru, atau memilih alur kerja yang sudah ada untuk memperbarui tetapi belum men-deploy-nya.
- Dalam definisi alur kerja, tambahkan langkah untuk membuat endpoint callback:
YAML
- create_callback: call: events.create_callback_endpoint args: http_callback_method: "METHOD" result: callback_details
JSON
[ { "create_callback": { "call": "events.create_callback_endpoint", "args": { "http_callback_method": "METHOD" }, "result": "callback_details" } } ]
Ganti
METHOD
dengan metode HTTP yang diharapkan, salah satu dariGET
,HEAD
,POST
,PUT
,DELETE
,OPTIONS
, atauPATCH
. Nilai defaultnya adalahPOST
.Hasilnya adalah peta,
callback_details
, dengan kolomurl
yang menyimpan URL endpoint yang dibuat.Endpoint callback sekarang siap menerima permintaan masuk dengan metode HTTP yang ditentukan. URL endpoint yang dibuat dapat digunakan untuk memicu callback dari proses di luar alur kerja; misalnya, dengan meneruskan URL ke Cloud Function.
- Dalam definisi alur kerja, tambahkan langkah untuk menunggu permintaan callback:
YAML
- await_callback: call: events.await_callback args: callback: ${callback_details} timeout: TIMEOUT result: callback_request
JSON
[ { "await_callback": { "call": "events.await_callback", "args": { "callback": "${callback_details}", "timeout": TIMEOUT }, "result": "callback_request" } } ]
Ganti
TIMEOUT
dengan jumlah detik maksimum yang harus ditunggu oleh alur kerja untuk permintaan. Defaultnya adalah 43200 (12 jam). Jika waktu berlalu sebelum permintaan diterima,TimeoutError
akan dimunculkan.Perhatikan bahwa ada durasi eksekusi maksimum. Untuk informasi selengkapnya, lihat batas permintaan.
Peta
callback_details
dari langkahcreate_callback
sebelumnya diteruskan sebagai argumen. - Deploy alur kerja Anda untuk menyelesaikan pembuatan atau pembaruan.
Saat permintaan diterima, semua detail permintaan akan disimpan di peta
callback_request
. Kemudian, Anda memiliki akses ke seluruh permintaan HTTP, termasuk header, isi, dan petaquery
untuk parameter kueri apa pun. Contoh:YAML
http_request: body: headers: {...} method: GET query: {} url: "/v1/projects/350446661175/locations/us-central1/workflows/workflow-1/executions/46804f42-dc83-46d6-87e4-93962866ed81/callbacks/49c80102-74d2-49cd-a70e-805a9fded94f_2de9b413-6332-412d-99c3-d7e9b6eeeda2" received_time: 2021-06-24 12:49:16.988072651 -0700 PDT m=+742581.005780667 type: HTTP
JSON
{ "http_request":{ "body":null, "headers":{ ... }, "method":"GET", "query":{ }, "url":"/v1/projects/350446661175/locations/us-central1/workflows/workflow-1/executions/46804f42-dc83-46d6-87e4-93962866ed81/callbacks/49c80102-74d2-49cd-a70e-805a9fded94f_2de9b413-6332-412d-99c3-d7e9b6eeeda2" }, "received_time":"2021-06-24 12:49:16.988072651 -0700 PDT m=+742581.005780667", "type":"HTTP" }
Jika isi HTTP berupa teks atau JSON, Workflows akan mencoba mendekode isi tersebut; jika tidak, byte mentah akan ditampilkan.
Mengizinkan permintaan ke endpoint callback
Untuk mengirim permintaan ke endpoint callback, layanan Google Cloud seperti Cloud Run dan Cloud Functions, serta layanan pihak ketiga, harus diizinkan untuk melakukannya dengan memiliki izin Identity and Access Management (IAM) yang sesuai; khususnya, workflows.callbacks.send
(disertakan dalam peran Workflows Invoker).
Membuat permintaan langsung
Cara termudah untuk membuat kredensial yang memiliki masa aktif singkat untuk akun layanan adalah dengan membuat permintaan langsung. Dua identitas terlibat dalam alur ini: pemanggil, dan akun layanan yang kredensialnya dibuat. Panggilan ke alur kerja dasar di halaman ini adalah contoh permintaan langsung. Untuk mengetahui informasi selengkapnya, baca Menggunakan IAM untuk mengontrol akses dan Izin permintaan langsung.
Membuat token akses OAuth 2.0
Untuk mengizinkan aplikasi memanggil endpoint callback, Anda dapat membuat
token akses OAuth 2.0 untuk akun layanan yang terkait dengan alur kerja.
Dengan asumsi bahwa Anda memiliki izin yang diperlukan (untuk peran Workflows Editor
atau Workflows Admin
, dan Service Account Token Creator
), Anda juga dapat membuat token sendiri dengan menjalankan metode generateAccessToken
.
Jika permintaan generateAccessToken
berhasil, isi respons
yang ditampilkan berisi token akses OAuth 2.0 dan waktu habis masa berlaku. (Secara default, token akses OAuth 2.0 berlaku maksimal selama 1 jam.) Misalnya:
{ "accessToken": "eyJ0eXAi...NiJ9", "expireTime": "2020-04-07T15:01:23.045123456Z" }
accessToken
kemudian dapat digunakan dalam panggilan curl ke URL endpoint
callback seperti dalam contoh berikut:
curl -X GET -H "Authorization: Bearer ACCESS_TOKEN_STRING" CALLBACK_URL
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer ACCESS_TOKEN_STRING" -d '{"foo" : "bar"}' CALLBACK_URL
Membuat token OAuth untuk Cloud Function
Jika memanggil callback dari Cloud Function menggunakan akun layanan yang sama dengan alur kerja dan di project yang sama, Anda dapat membuat token akses OAuth di fungsi itu sendiri. Contoh:
Untuk mengetahui konteks selengkapnya, lihat tutorial tentang Membuat alur kerja yang memerlukan interaksi manusia menggunakan callback.
Minta akses offline
Token akses akan habis masa berlakunya secara berkala dan menjadi kredensial yang tidak valid untuk permintaan API terkait. Anda dapat me-refresh token akses tanpa meminta izin kepada pengguna jika Anda meminta akses offline ke cakupan yang terkait dengan token tersebut. Meminta akses offline adalah persyaratan untuk setiap aplikasi yang perlu mengakses Google API saat pengguna tidak ada. Untuk mengetahui informasi selengkapnya, lihat Memperbarui token akses (akses offline).
Mencoba alur kerja callback dasar
Anda dapat membuat alur kerja dasar, lalu menguji panggilan ke endpoint callback
alur kerja tersebut menggunakan curl. Anda harus memiliki izin Workflows Editor
atau
Workflows Admin
yang diperlukan untuk project tempat alur kerja berada.
-
Buat dan deploy alur kerja berikut, lalu
execute.
YAML
- create_callback: call: events.create_callback_endpoint args: http_callback_method: "GET" result: callback_details - print_callback_details: call: sys.log args: severity: "INFO" text: ${"Listening for callbacks on " + callback_details.url} - await_callback: call: events.await_callback args: callback: ${callback_details} timeout: 3600 result: callback_request - print_callback_request: call: sys.log args: severity: "INFO" text: ${"Received " + json.encode_to_string(callback_request.http_request)} - return_callback_result: return: ${callback_request.http_request}
JSON
[ { "create_callback": { "call": "events.create_callback_endpoint", "args": { "http_callback_method": "GET" }, "result": "callback_details" } }, { "print_callback_details": { "call": "sys.log", "args": { "severity": "INFO", "text": "${\"Listening for callbacks on \" + callback_details.url}" } } }, { "await_callback": { "call": "events.await_callback", "args": { "callback": "${callback_details}", "timeout": 3600 }, "result": "callback_request" } }, { "print_callback_request": { "call": "sys.log", "args": { "severity": "INFO", "text": "${\\"Received \\" + json.encode_to_string(callback_request.http_request)}" } } }, { "return_callback_result": { "return": "${callback_request.http_request}" } } ]
Setelah menjalankan alur kerja, status eksekusi alur kerja adalah
ACTIVE
hingga permintaan callback diterima atau waktu tunggu berlalu. - Konfirmasi status eksekusi dan ambil URL callback:
Konsol
-
Di konsol Google Cloud, buka halaman Workflows:
Buka Workflows -
Klik nama alur kerja yang baru saja Anda jalankan.
Status eksekusi alur kerja akan ditampilkan.
- Klik tab Logs.
Cari entri log yang mirip dengan yang berikut ini:
Listening for callbacks on https://workflowexecutions.googleapis.com/v1/projects/...
- Salin URL callback untuk digunakan di perintah berikutnya.
gcloud
- Pertama, ambil ID eksekusi:
gcloud logging read "Listening for callbacks" --freshness=DURATION
GantiDURATION
dengan durasi waktu yang sesuai untuk membatasi entri log yang ditampilkan (jika Anda telah menjalankan alur kerja beberapa kali).Misalnya,
--freshness=t10m
menampilkan entri log yang berdurasi tidak lebih dari 10 menit. Untuk mengetahui detailnya, lihatgcloud topic datetimes
.ID eksekusi ditampilkan. Perhatikan bahwa URL callback juga ditampilkan di kolom
textPayload
. Salin kedua nilai tersebut untuk digunakan dalam langkah-langkah berikut. - Jalankan perintah berikut:
-
- Kini Anda dapat memanggil endpoint callback menggunakan perintah curl:
curl -X GET -H "Authorization: Bearer $(gcloud auth print-access-token)" CALLBACK_URL
Perhatikan bahwa untuk endpoint
POST
, Anda harus menggunakan header representasiContent-Type
. Contoh:curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $(gcloud auth print-access-token)" -d '{"foo" : "bar"}' CALLBACK_URL
Ganti
CALLBACK_URL
dengan URL yang Anda salin di langkah sebelumnya. - Melalui Konsol Google Cloud atau menggunakan Google Cloud CLI,
pastikan status eksekusi alur kerja sekarang adalah
SUCCEEDED
. - Cari entri log dengan
textPayload
yang ditampilkan dan terlihat seperti berikut:Received {"body":null,"headers":...
Sampel
Contoh ini menunjukkan sintaksis.
Menangkap error waktu tunggu
Contoh ini ditambahkan ke contoh sebelumnya dengan menangkap error waktu tunggu, dan menulis error tersebut ke log sistem.
YAML
main: steps: - create_callback: call: events.create_callback_endpoint args: http_callback_method: "GET" result: callback_details - print_callback_details: call: sys.log args: severity: "INFO" text: ${"Listening for callbacks on " + callback_details.url} - await_callback: try: call: events.await_callback args: callback: ${callback_details} timeout: 3600 result: callback_request except: as: e steps: - log_error: call: sys.log args: severity: "ERROR" text: ${"Received error " + e.message} next: end - print_callback_result: call: sys.log args: severity: "INFO" text: ${"Received " + json.encode_to_string(callback_request.http_request)}
JSON
{ "main": { "steps": [ { "create_callback": { "call": "events.create_callback_endpoint", "args": { "http_callback_method": "GET" }, "result": "callback_details" } }, { "print_callback_details": { "call": "sys.log", "args": { "severity": "INFO", "text": "${\"Listening for callbacks on \" + callback_details.url}" } } }, { "await_callback": { "try": { "call": "events.await_callback", "args": { "callback": "${callback_details}", "timeout": 3600 }, "result": "callback_request" }, "except": { "as": "e", "steps": [ { "log_error": { "call": "sys.log", "args": { "severity": "ERROR", "text": "${\"Received error \" + e.message}" }, "next": "end" } } ] } } }, { "print_callback_result": { "call": "sys.log", "args": { "severity": "INFO", "text": "${\"Received \" + json.encode_to_string(callback_request.http_request)}" } } } ] } }
Menunggu callback dalam loop percobaan ulang
Contoh ini memodifikasi sampel sebelumnya dengan menerapkan langkah percobaan ulang. Dengan menggunakan predikat percobaan ulang kustom, alur kerja akan mencatat peringatan saat waktu tunggu habis, lalu mencoba ulang waktu tunggu di endpoint callback hingga lima kali. Jika kuota percobaan ulang habis sebelum callback diterima, error waktu tunggu terakhir akan menyebabkan alur kerja gagal.
YAML
main: steps: - create_callback: call: events.create_callback_endpoint args: http_callback_method: "GET" result: callback_details - print_callback_details: call: sys.log args: severity: "INFO" text: ${"Listening for callbacks on " + callback_details.url} - await_callback: try: call: events.await_callback args: callback: ${callback_details} timeout: 60.0 result: callback_request retry: predicate: ${log_timeout} max_retries: 5 backoff: initial_delay: 1 max_delay: 10 multiplier: 2 - print_callback_result: call: sys.log args: severity: "INFO" text: ${"Received " + json.encode_to_string(callback_request.http_request)} log_timeout: params: [e] steps: - when_to_repeat: switch: - condition: ${"TimeoutError" in e.tags} steps: - log_error_and_retry: call: sys.log args: severity: "WARNING" text: "Timed out waiting for callback, retrying" - exit_predicate: return: true - otherwise: return: false
JSON
{ "main": { "steps": [ { "create_callback": { "call": "events.create_callback_endpoint", "args": { "http_callback_method": "GET" }, "result": "callback_details" } }, { "print_callback_details": { "call": "sys.log", "args": { "severity": "INFO", "text": "${\"Listening for callbacks on \" + callback_details.url}" } } }, { "await_callback": { "try": { "call": "events.await_callback", "args": { "callback": "${callback_details}", "timeout": 60 }, "result": "callback_request" }, "retry": { "predicate": "${log_timeout}", "max_retries": 5, "backoff": { "initial_delay": 1, "max_delay": 10, "multiplier": 2 } } } }, { "print_callback_result": { "call": "sys.log", "args": { "severity": "INFO", "text": "${\"Received \" + json.encode_to_string(callback_request.http_request)}" } } } ] }, "log_timeout": { "params": [ "e" ], "steps": [ { "when_to_repeat": { "switch": [ { "condition": "${\"TimeoutError\" in e.tags}", "steps": [ { "log_error_and_retry": { "call": "sys.log", "args": { "severity": "WARNING", "text": "Timed out waiting for callback, retrying" } } }, { "exit_predicate": { "return": true } } ] } ] } }, { "otherwise": { "return": false } } ] } }