發出 HTTP 要求

您可以定義工作流程步驟,以便發出 HTTP 呼叫,並將呼叫的回應指派給變數。舉例來說,您可以透過 HTTP 要求叫用 Google Cloud服務,例如 Cloud Run 函式或 Cloud Run

請勿將透過 HTTP 要求叫用 Google Cloud 服務與使用工作流程連接器執行 API 作業混淆。連接器可簡化呼叫服務,因為它會為您處理要求的格式化作業,並提供方法和引數,讓您不必瞭解 Google Cloud API 的詳細資料。

叫用 HTTP 端點

這類步驟可讓您提出 HTTP 要求。同時支援 HTTP 和 HTTPS 要求。最常見的 HTTP 要求方法都有呼叫快捷方式 (例如 http.gethttp.post),但您可以將 call 欄位設為 http.request,並使用 method 欄位指定要求類型,藉此發出任何類型的 HTTP 要求。

YAML

  - STEP_NAME:
      call: HTTP_REQUEST
      args:
          url: URL_VALUE
          method: REQUEST_METHOD
          private_service_name: "REGISTERED_SERVICE"
          headers:
              HEADER_KEY:HEADER_VALUE
              ...
          body:
              BODY_KEY:BODY_VALUE
              ...
          query:
              QUERY_KEY:QUERY_VALUE
              ...
          auth:
              type: AUTH_TYPE
              scope: AUTH_SCOPE
              scopes: AUTH_SCOPE
              audience: AUDIENCE
          timeout: TIMEOUT_IN_SECONDS
      result: RESULT_VALUE
    

JSON

  [
    {
      "STEP_NAME": {
        "call": "HTTP_REQUEST",
        "args": {
          "url": "URL_VALUE",
          "method": "REQUEST_METHOD",
          "private_service_name": "REGISTERED_SERVICE",
          "headers": {"HEADER_KEY":"HEADER_VALUE",
          ...
          },
          "body": {"BODY_KEY":"BODY_VALUE",
          ...
          },
          "query": {"QUERY_KEY":"QUERY_VALUE",
          ...
          },
          "auth": {
            "type":"AUTH_TYPE",
            "scope":"AUTH_SCOPE",
            "scopes":"AUTH_SCOPE",
            "audience":"AUDIENCE"
          },
          "timeout": "TIMEOUT_IN_SECONDS"
        },
        "result": "RESULT_VALUE"
      }
    }
  ]
    

請依指示取代下列項目:

  • HTTP_REQUEST:必要。請針對 HTTP 要求使用下列其中一種方法:
    • http.delete
    • http.get
    • http.patch
    • http.post
    • http.put
    • http.request
  • URL_VALUE:必要。傳送要求的網址。
  • REQUEST_METHOD:如果使用呼叫類型 http.request,則為必要。要使用的 HTTP 要求方法類型。例如:
    • GET
    • POST
    • PATCH
    • DELETE
  • REGISTERED_SERVICE:選用。格式為 projects/PROJECT_ID/locations/LOCATION/namespaces/NAMESPACE_NAME/services/SERVICE_NAME 的已註冊 Service Directory 服務名稱。詳情請參閱「呼叫符合 VPC Service Controls 規範的私人端點」。
  • HEADER_KEY:HEADER_VALUE:選用。提供 API 輸入內容的標頭欄位。

    如果使用 Content-Type 標頭指定要求主體的媒體類型,系統只支援下列類型:

    • application/jsonapplication/type+json:必須是地圖
    • application/x-www-form-urlencoded:必須是未經編碼的字串
    • text/type:必須是字串

    如果指定 Content-Type 標頭,內文就會依規定編碼。例如,可能會是 JSON 或經過網址編碼的內容。

    如果使用 User-Agent 標頭來識別要求使用者代理程式,則適用下列規定:

    • 預設值為 GoogleCloudWorkflows; (+https://cloud.google.com/workflows/docs)
    • 如果指定了值,系統會在該值後方附加 GoogleCloudWorkflows; (+https://cloud.google.com/workflows/docs)

      舉例來說,如果指定 User-Agent: "MY_USER_AGENT_VALUE",HTTP 要求標頭會如下所示 (在指定值和附加的預設值之間留有空格):

      MY_USER_AGENT_VALUE GoogleCloudWorkflows; (+https://cloud.google.com/workflows/docs)
  • BODY_KEY:BODY_VALUE:選用。供 API 輸入內容的內容欄位。

    如果未指定 Content-Type 標頭,且存在要求主體,則適用下列規定:

    • 如果主體值是位元組,標頭會設為 Content-Type: application/octet-stream
    • 否則,內文會採用 JSON 編碼,標頭則會設為 Content-Type: application/json; charset=utf-8
    以下範例是與 JSON 酬載等同的主體結構:

    YAML

    body:
      requests:
      - image:
          source:
            gcsImageUri: ${gsUri}
        features:
        - type: LABEL_DETECTION
        - type: SAFE_SEARCH_DETECTION
        - type: IMAGE_PROPERTIES
    result: imageAnalysisResponse

    JSON

    {
      "requests":[
        {
          "image": {
            "source": {
                "gcsUri": "img.png"
            }
          },
          "features": [
            { "type":"LABEL_DETECTION" },
            { "type":"SAFE_SEARCH_DETECTION" },
            { "type":"IMAGE_PROPERTIES" },
          ]
        }
      ]
    }
  • QUERY_KEY:QUERY_VALUE:選用。查詢欄位,為 API 提供輸入內容。
  • AUTH_TYPE:選用。如果要呼叫的 API 需要驗證,則必須提供這個屬性。請使用 OIDCOAuth2。詳情請參閱「透過工作流程提出經過驗證的要求」。
    • AUTH_SCOPE:選用。限制應用程式對使用者帳戶的存取權。使用 scopescopes 鍵。

      scope 鍵支援字串或字串清單。例如:

      "https://www.googleapis.com/auth/cloud-platform"

      ["https://www.googleapis.com/auth/cloud-platform", "scope2", "scope3"]

      scopes 鍵除了支援字串或字串清單,也支援以空格和半形逗號分隔的字串。例如:

      "https://www.googleapis.com/auth/cloud-platform scope2 scope3"

      "https://www.googleapis.com/auth/cloud-platform,scope2,scope3"

      詳情請參閱「 Google API 適用的 OAuth 2.0 範圍」。

    • AUDIENCE:選用。指定 OIDC 權杖的目標對象。根據預設,此值會設為與 url 相同,但應設為服務的根網址。例如:https://region-project.cloudfunctions.net/hello_world
  • TIMEOUT_IN_SECONDS:選用。允許要求執行多久 (以秒為單位) 後才擲回例外狀況。上限為 1800 秒。
  • RESULT_VALUE:選用。儲存 HTTP 叫用步驟結果的變數名稱。

存取儲存在變數中的 HTTP 回應資料

如果回應的 Content-Type 標頭指定 application/json 媒體類型,則儲存在變數中的 JSON 回應會自動轉換為可存取的地圖。

如有需要,請修改要呼叫的 API,為 Content-Type 回應標頭指定 application/json 媒體類型。否則,您可以使用 json.decodetext.encode 函式將回應主體轉換為對應項目。例如:

json.decode(text.encode(RESPONSE_FROM_API))

工作流程包含內建的剖析器,可用於存取這類資料。如要存取 HTTP 回應中的欄位,請使用下列語法:

${VARIABLE_NAME.body|code|headers.PATH_TO_FIELD}

更改下列內容:

  • VARIABLE_NAME:儲存 JSON 回應的工作流程變數名稱。
  • body:使用 body 欄位存取 HTTP 回應的主體。
  • code:使用 code 欄位存取 HTTP 回應代碼。
  • headers:使用 headers 欄位依名稱存取 HTTP 回應標頭。
  • PATH_TO_FIELD:您要存取的 JSON 回應中欄位的路徑。這可能是欄位名稱,如果欄位是巢狀結構的物件,則可能會採用 object1.object2.field 的形式。

舉例來說,如果 API 傳回 {"age":50},且工作流程將該回應儲存在名為 age_response 的變數中,以下範例會傳回 age 欄位的值,在本例中為 50

age_response.body.age

範例

以下範例說明語法。

指派 API 呼叫的回應

除非您自行輸入搜尋字詞,否則這個範例會使用您的 Google Cloud位置建構搜尋字詞,並將搜尋字詞傳送至 Wikipedia API。系統會傳回相關的維基百科文章清單。

YAML

main:
  params: [input]
  steps:
    - checkSearchTermInInput:
        switch:
          - condition: '${"searchTerm" in input}'
            assign:
              - searchTerm: '${input.searchTerm}'
            next: readWikipedia
    - getLocation:
        call: sys.get_env
        args:
          name: GOOGLE_CLOUD_LOCATION
        result: location
    - setFromCallResult:
        assign:
          - searchTerm: '${text.split(location, "-")[0]}'
    - readWikipedia:
        call: http.get
        args:
          url: 'https://en.wikipedia.org/w/api.php'
          query:
            action: opensearch
            search: '${searchTerm}'
        result: wikiResult
    - returnOutput:
        return: '${wikiResult.body[1]}'

JSON

{
  "main": {
    "params": [
      "input"
    ],
    "steps": [
      {
        "checkSearchTermInInput": {
          "switch": [
            {
              "condition": "${\"searchTerm\" in input}",
              "assign": [
                {
                  "searchTerm": "${input.searchTerm}"
                }
              ],
              "next": "readWikipedia"
            }
          ]
        }
      },
      {
        "getLocation": {
          "call": "sys.get_env",
          "args": {
            "name": "GOOGLE_CLOUD_LOCATION"
          },
          "result": "location"
        }
      },
      {
        "setFromCallResult": {
          "assign": [
            {
              "searchTerm": "${text.split(location, \"-\")[0]}"
            }
          ]
        }
      },
      {
        "readWikipedia": {
          "call": "http.get",
          "args": {
            "url": "https://en.wikipedia.org/w/api.php",
            "query": {
              "action": "opensearch",
              "search": "${searchTerm}"
            }
          },
          "result": "wikiResult"
        }
      },
      {
        "returnOutput": {
          "return": "${wikiResult.body[1]}"
        }
      }
    ]
  }
}

發出外部 HTTP POST 要求

這個範例會向外部 HTTP 端點發出 POST 要求。

YAML

- send_message:
    call: http.post
    args:
      url: https://www.example.com/endpoint
      body:
        some_val: "Hello World"
        another_val: 123
    result: the_message
- return_value:
    return: ${the_message.body}

JSON

[
  {
    "send_message": {
      "call": "http.post",
      "args": {
        "url": "https://www.example.com/endpoint",
        "body": {
          "some_val": "Hello World",
          "another_val": 123
        }
      },
      "result": "the_message"
    }
  },
  {
    "return_value": {
      "return": "${the_message.body}"
    }
  }
]

使用標頭建立外部 HTTP GET 要求

這個範例會使用自訂標頭提出 HTTP GET 要求。您也可以在提出其他類型的 HTTP 要求時,提供自訂標頭定義。

YAML

- get_message:
    call: http.get
    args:
      url: https://www.example.com/endpoint
      headers:
        Content-Type: "text/plain"
      query:
        some_val: "Hello World"
        another_val: 123
    result: the_message
- return_value:
    return: ${the_message.body}

JSON

[
  {
    "get_message": {
      "call": "http.get",
      "args": {
        "url": "https://www.example.com/endpoint",
        "headers": {
          "Content-Type": "text/plain"
        },
        "query": {
          "some_val": "Hello World",
          "another_val": 123
        }
      },
      "result": "the_message"
    }
  },
  {
    "return_value": {
      "return": "${the_message.body}"
    }
  }
]

向 Cloud Run 函式提出要求時,使用 OIDC 進行驗證

這個範例會在指定網址後,將 auth 部分新增至工作流程定義的 args 部分,以便使用 OIDC 提出 HTTP 要求。

YAML

- call_my_function:
    call: http.post
    args:
      url: https://us-central1-myproject123.cloudfunctions.net/myfunc1
      auth:
        type: OIDC
      body:
        some_val: "Hello World"
        another_val: 123
    result: the_message
- return_value:
    return: ${the_message.body}

JSON

[
  {
    "call_my_function": {
      "call": "http.post",
      "args": {
        "url": "https://us-central1-myproject123.cloudfunctions.net/myfunc1",
        "auth": {
          "type": "OIDC"
        },
        "body": {
          "some_val": "Hello World",
          "another_val": 123
        }
      },
      "result": "the_message"
    }
  },
  {
    "return_value": {
      "return": "${the_message.body}"
    }
  }
]

擷取及處理 HTTP 要求錯誤

這個範例會根據 GET 要求傳回的 HTTP 狀態碼,實作自訂例外狀況處理程序。工作流程會擷取潛在例外狀況,並傳回預先定義的錯誤訊息。如果系統無法辨識例外狀況,工作流程執行作業就會失敗,並擲回 GET 要求傳回的例外狀況。如要瞭解其他錯誤標記,請參閱「工作流程錯誤」。

YAML

# Use a custom exception handler to catch exceptions and return predefined
# error messages; if the exception isn't recognized, the workflow
# execution fails and throws the exception returned by the GET request
- read_item:
    try:
      call: http.get
      args:
        url: https://example.com/someapi
        auth:
          type: OIDC
      result: API_response
    except:
      as: e
      steps:
        - known_errors:
            switch:
              - condition: ${not("HttpError" in e.tags)}
                next: connection_problem
              - condition: ${e.code == 404}
                next: url_not_found
              - condition: ${e.code == 403}
                next: auth_problem
        - unhandled_exception:
            raise: ${e}
- url_found:
    return: ${API_response.body}
- connection_problem:
    return: "Connection problem; check URL"
- url_not_found:
    return: "Sorry, URL wasn't found"
- auth_problem:
    return: "Authentication error"

JSON

[
  {
    "read_item": {
      "try": {
        "call": "http.get",
        "args": {
          "url": "https://example.com/someapi",
          "auth": {
            "type": "OIDC"
          }
        },
        "result": "API_response"
      },
      "except": {
        "as": "e",
        "steps": [
          {
            "known_errors": {
              "switch": [
                {
                  "condition": "${not(\"HttpError\" in e.tags)}",
                  "next": "connection_problem"
                },
                {
                  "condition": "${e.code == 404}",
                  "next": "url_not_found"
                },
                {
                  "condition": "${e.code == 403}",
                  "next": "auth_problem"
                }
              ]
            }
          },
          {
            "unhandled_exception": {
              "raise": "${e}"
            }
          }
        ]
      }
    }
  },
  {
    "url_found": {
      "return": "${API_response.body}"
    }
  },
  {
    "connection_problem": {
      "return": "Connection problem; check URL"
    }
  },
  {
    "url_not_found": {
      "return": "Sorry, URL wasn't found"
    }
  },
  {
    "auth_problem": {
      "return": "Authentication error"
    }
  }
]

後續步驟