Fazer uma solicitação HTTP

É possível definir uma etapa de fluxo de trabalho que faça uma chamada HTTP e atribuir a resposta da chamada a uma variável. Por exemplo, é possível invocar um serviço do Google Cloud como o Cloud Functions ou o Cloud Run por uma solicitação HTTP.

Invocar um endpoint HTTP

Esse tipo de etapa permite fazer uma solicitação HTTP. Tanto solicitações HTTP como HTTPS são compatíveis. Os métodos de solicitação HTTP mais comuns têm um atalho de chamada (como http.get e http.post), mas é possível fazer qualquer tipo de solicitação HTTP definindo o campo call como http.request e especificando o tipo de solicitação usando o campo method.

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"
      }
    }
  ]
    

Substitua:

  • HTTP_REQUEST: obrigatório. Use uma das seguintes opções: Para solicitações HTTP:
    • http.delete
    • http.get
    • http.patch
    • http.post
    • http.put
    • http.request
  • URL_VALUE: obrigatório. URL para onde a solicitação é enviada.
  • REQUEST_METHOD: obrigatório se o tipo de chamada estiver sendo usado. http.request. O tipo de método de solicitação HTTP a ser usado. Por exemplo:
    • GET
    • POST
    • PATCH
    • DELETE
  • REGISTERED_SERVICE: opcional. Um registrado Nome do serviço do Diretório de serviços no formato projects/PROJECT_ID/locations/LOCATION/namespaces/NAMESPACE_NAME/services/SERVICE_NAME: Para mais informações, consulte Invoque um Endpoint particular compatível com o VPC Service Controls.
  • HEADER_KEYhHEADER_VALUE opcional. Campos do cabeçalho para fornecer entrada à API.

    Se você usar um cabeçalho Content-Type para especificar o tipo de mídia do corpo da solicitação, somente os tipos a seguir serão compatíveis:

    • application/json ou application/type+json: precisa ser um mapa
    • application/x-www-form-urlencoded: precisa ser um código não codificado corda
    • É preciso que text/type seja uma string.

    Se um cabeçalho Content-Type for especificado, o corpo será codificados conforme prescrito. Por exemplo, pode ser JSON ou codificado em URL.

    Se você estiver usando um cabeçalho User-Agent para identificar o user agent solicitante, as seguintes condições serão aplicadas:

    • O padrão é GoogleCloudWorkflows; (+https://cloud.google.com/workflows/docs)
    • Se um valor for especificado, GoogleCloudWorkflows; (+https://cloud.google.com/workflows/docs) está anexado ao valor,

      Por exemplo, se User-Agent: "MY_USER_AGENT_VALUE" for especificado, o cabeçalho da solicitação HTTP será o seguinte (com um espaço entre o valor especificado e o padrão anexado):

      MY_USER_AGENT_VALUE GoogleCloudWorkflows; (+https://cloud.google.com/workflows/docs)
  • BODY_KEYhBODY_VALUE opcional. Campos do corpo para fornecer a entrada à API.

    Se um cabeçalho Content-Type não for especificado, e se uma solicitação o corpo estiver presente, o seguinte será aplicado:

    • Se o valor do corpo for bytes, o cabeçalho será definido como Content-Type: application/octet-stream:
    • Caso contrário, o corpo será codificado em JSON e o cabeçalho será definido como Content-Type: application/json; charset=utf-8:
    . O exemplo a seguir é de uma estrutura de corpo equivalente a um payload 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_KEYhQUERY_VALUE opcional. Campos de consulta para fornecer a entrada à API.
  • AUTH_TYPE: opcional. Obrigatório se a API que está sendo chamada exige autenticação. Use OIDC ou OAuth2. Para mais informações, consulte Fazer autenticação solicitações de um fluxo de trabalho.
    • AUTH_SCOPE: opcional. Limita o acesso de um aplicativo à conta de um usuário. Use a tecla scope ou scopes.

      A chave scope oferece suporte a uma string ou lista de strings. Exemplo:

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

      ou

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

      A chave scopes, além de oferecer suporte a uma string ou lista de strings, suporta espaço e strings separadas por vírgula. Exemplo:

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

      ou

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

      Para mais informações, consulte Escopos do OAuth 2.0 para APIs do Google.

    • AUDIENCE: opcional. Especifica o público-alvo do token OIDC. Por padrão, ele é definido como o mesmo valor de url. No entanto, ele precisa ser definido como o URL raiz do serviço. Exemplo: https://region-project.cloudfunctions.net/hello_world.
  • TIMEOUT_IN_SECONDS: opcional. Quanto tempo em segundos uma solicitação pode ser executada antes de gerar uma exceção. O máximo é 1.800 segundos.
  • RESULT_VALUE: opcional. Nome da variável em que o resultado de uma etapa de invocação HTTP é armazenado.

Acessar dados de resposta HTTP salvos em uma variável

Se o cabeçalho Content-Type da resposta especificar uma application/json, a resposta JSON armazenada em um é convertida automaticamente em um mapa que pode ser acessado.

Se necessário, modifique a API que está sendo chamada para especificar um application/json tipo de mídia para Content-Type no cabeçalho da resposta. Caso contrário, use o método json.decode e text.encode para converter o corpo da resposta em um mapa. Exemplo:

json.decode(text.encode(RESPONSE_FROM_API))

O Workflows tem um analisador integrado para acessar esses dados. Para acessar os campos da resposta HTTP, use a seguinte sintaxe:

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

Substitua:

  • VARIABLE_NAME: o nome da variável do fluxo de trabalho em que salva uma resposta JSON.
  • body: use o campo body para acessar o corpo da resposta HTTP.
  • code: use o campo code para acessar o código de resposta HTTP.
  • headers: use o campo headers para acessar os cabeçalhos de resposta HTTP por nome.
  • PATH_TO_FIELD: o caminho para o campo no JSON. que você quer acessar. Pode ser simplesmente o nome do campo ou, se o campo está aninhado dentro de um objeto, pode assumir a forma de object1.object2.field.

Por exemplo, se uma API retorna {"age":50} e um fluxo de trabalho armazena essa resposta em uma variável chamada age_response, o exemplo a seguir retorna o valor do campo age. Nesse caso, 50:

age_response.body.age

Amostras

Estas amostras demonstram a sintaxe.

Atribuir a resposta de uma chamada de API

A menos que você insira seu próprio termo de pesquisa, este exemplo usa sua conta do Google Cloud localização para construir um termo de pesquisa, que ele passa para o API Wikipedia. Um lista de artigos relacionados da Wikipédia é retornada.

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]}"
        }
      }
    ]
  }
}

Fazer uma solicitação POST HTTP externa

Este exemplo faz uma solicitação POST para um endpoint HTTP externo.

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}"
    }
  }
]

Fazer uma solicitação HTTP GET externa com cabeçalhos

Este exemplo faz uma solicitação HTTP GET com um cabeçalho personalizado. Também é possível fornecer definições personalizadas de cabeçalho ao fazer outros tipos de solicitações 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}"
    }
  }
]

Usar o OIDC para autenticar ao fazer uma solicitação ao Cloud Functions

Neste exemplo, fazemos uma solicitação HTTP usando o OIDC adicionando uma seção auth à seção args da definição do fluxo de trabalho, depois de especificar o URL.

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}"
    }
  }
]

Detectar e processar erros de solicitação HTTP

Este exemplo implementa um gerenciador de exceções personalizado com base no código de status HTTP retornados pela solicitação GET. O fluxo de trabalho captura uma possível exceção e retorna uma mensagem de erro predefinida. Se uma exceção não for reconhecida, o a execução do fluxo de trabalho falha e gera a exceção quando retornada pelo GET solicitação. Para outras tags de erro, consulte Erros de fluxo de trabalho.

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"
    }
  }
]

A seguir