Envoyer une requête HTTP

Vous pouvez définir une étape de workflow qui effectue un appel HTTP et attribue la réponse de l'appel à une variable. Par exemple, vous pouvez appeler un service Google Cloud tel que Cloud Functions ou Cloud Run via une requête HTTP.

Appeler un point de terminaison HTTP

Ce type d'étape vous permet d'effectuer une requête HTTP. Les requêtes HTTP et HTTPS sont toutes deux acceptées. Les méthodes de requête HTTP les plus courantes possèdent un raccourci d'appel (tel que http.get et http.post), mais vous pouvez effectuer n'importe quel type de requête HTTP en définissant le champ call sur http.request et en spécifiant le type de requête à l'aide du champ 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"
      }
    }
  ]
    

Remplacez les éléments suivants :

  • HTTP_REQUEST : Obligatoire. Utilisez l'une des méthodes suivantes pour les requêtes HTTP :
    • http.delete
    • http.get
    • http.patch
    • http.post
    • http.put
    • http.request
  • URL_VALUE : Obligatoire. URL vers laquelle la requête est envoyée.
  • REQUEST_METHOD: obligatoire si vous utilisez le type d'appel http.request. Type de la méthode de requête HTTP à utiliser. Exemple :
    • GET
    • POST
    • PATCH
    • DELETE
  • REGISTERED_SERVICE : Facultatif. Nom de service enregistré de l'Annuaire des services, au format projects/PROJECT_ID/locations/LOCATION/namespaces/NAMESPACE_NAME/services/SERVICE_NAME. Pour en savoir plus, consultez la section Appeler un point de terminaison privé compatible avec VPC Service Controls.
  • HEADER_KEY:HEADER_VALUE : facultatif. Champs d'en-tête pour fournir l'entrée à l'API.

    Si vous utilisez un en-tête Content-Type pour spécifier le type de contenu du corps de la requête, seuls les types suivants sont acceptés:

    • application/json ou application/type+json : doit être une carte
    • application/x-www-form-urlencoded : doit être une chaîne non encodée
    • text/type-doit être une chaîne.

    Si un en-tête Content-Type est spécifié, le corps est encodé comme prescrit. Il peut, par exemple, être au format JSON ou encodé en URL.

    Si vous utilisez un en-tête User-Agent pour identifier le user-agent à l'origine de la requête, les critères suivants s'appliquent:

    • La valeur par défaut est GoogleCloudWorkflows; (+https://cloud.google.com/workflows/docs)
    • Si une valeur est spécifiée, GoogleCloudWorkflows; (+https://cloud.google.com/workflows/docs) est ajouté à cette valeur.

      Par exemple, si User-Agent: "MY_USER_AGENT_VALUE" est spécifié, l'en-tête de requête HTTP se présentera comme suit (avec un espace entre la valeur spécifiée et la valeur par défaut ajoutée):

      MY_USER_AGENT_VALUE GoogleCloudWorkflows; (+https://cloud.google.com/workflows/docs)
  • BODY_KEY:BODY_VALUE : facultatif. Champs de corps permettant de fournir des entrées à l'API.

    Si aucun en-tête Content-Type n'est spécifié et qu'un corps de requête est présent, les conditions suivantes s'appliquent:

    • Si la valeur du corps correspond à des octets, l'en-tête est défini sur Content-Type: application/octet-stream.
    • Sinon, le corps est encodé au format JSON et l'en-tête est défini sur Content-Type: application/json; charset=utf-8.
    L'exemple suivant illustre une structure de corps équivalente à une charge utile 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 : facultatif. Champs de requête permettant de fournir des entrées à l'API.
  • AUTH_TYPE : Facultatif. Obligatoire si l'API appelée nécessite une authentification. Utilisez OIDC ou OAuth2. Pour en savoir plus, consultez la section Envoyer des requêtes authentifiées à partir d'un workflow.
    • AUTH_SCOPE : Facultatif. Limite l'accès d'une application au compte d'un utilisateur. Utilisez la touche scope ou scopes.

      La clé scope accepte une chaîne ou une liste de chaînes. Exemple :

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

      ou

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

      La clé scopes, en plus d'accepter une chaîne ou une liste de chaînes, accepte les chaînes séparées par des espaces et des virgules. Exemple :

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

      ou

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

      Pour en savoir plus, consultez Champs d'application OAuth 2.0 pour les API Google.

    • AUDIENCE : Facultatif. Spécifie l'audience du jeton OIDC. Par défaut, cette valeur est définie sur la même valeur que url. Cependant, elle doit être définie sur l'URL racine de votre service. Exemple : https://region-project.cloudfunctions.net/hello_world.
  • TIMEOUT_IN_SECONDS : Facultatif. Durée, en secondes, pendant laquelle une requête est autorisée à s'exécuter avant de générer une exception. La valeur maximale est de 1 800 secondes.
  • RESULT_VALUE : Facultatif. Nom de la variable dans laquelle le résultat d'une étape d'appel HTTP est stocké.

Accéder aux données de réponse HTTP enregistrées dans une variable

Si l'en-tête Content-Type de la réponse spécifie un type de contenu application/json, la réponse JSON stockée dans une variable est automatiquement convertie en carte accessible.

Si nécessaire, modifiez l'API appelée pour spécifier un type de média application/json pour l'en-tête de réponse Content-Type. Sinon, vous pouvez utiliser les fonctions json.decode et text.encode pour convertir le corps de la réponse en carte. Exemple :

json.decode(text.encode(RESPONSE_FROM_API))

Workflows inclut un analyseur intégré permettant d'accéder à ces données. Pour accéder aux champs à partir de la réponse HTTP, utilisez la syntaxe suivante:

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

Remplacez les éléments suivants :

  • VARIABLE_NAME: nom de la variable de workflow dans laquelle vous avez enregistré une réponse JSON.
  • body: utilisez le champ body pour accéder au corps de la réponse HTTP.
  • code: utilisez le champ code pour accéder au code de réponse HTTP.
  • headers: utilisez le champ headers pour accéder aux en-têtes de réponse HTTP par nom.
  • PATH_TO_FIELD: chemin d'accès au champ de la réponse JSON auquel vous souhaitez accéder. Il peut s'agir d'un simple nom de champ. Si le champ est imbriqué dans un objet, il peut se présenter sous la forme object1.object2.field.

Par exemple, si une API renvoie {"age":50} et qu'un workflow stocke cette réponse dans une variable appelée age_response, l'exemple suivant renvoie la valeur du champ age ; Dans le cas présent, 50:

age_response.body.age

Exemples

Ces exemples illustrent la syntaxe.

Attribuer la réponse à partir d'un appel d'API

Sauf si vous saisissez votre propre terme de recherche, cet exemple utilise votre emplacement Google Cloud pour créer un terme de recherche, qu'il transmet à l'API Wikipédia. Une liste d'articles Wikipédia associés s'affiche.

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

Envoyer une requête HTTP POST externe

Cet exemple envoie une requête POST à un point de terminaison HTTP externe.

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

Créer une requête HTTP GET externe avec des en-têtes

Cet exemple effectue une requête HTTP GET avec un en-tête personnalisé. Vous pouvez également fournir des définitions d'en-têtes personnalisés lorsque vous effectuez d'autres types de requêtes 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}"
    }
  }
]

Utiliser OIDC pour l'authentification lors de l'envoi de requêtes à Cloud Functions

Cet exemple effectue une requête HTTP à l'aide d'OIDC en ajoutant une section auth à la section args de la définition du workflow, après avoir spécifié l'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}"
    }
  }
]

Détectez et gérez les erreurs de requêtes HTTP

Cet exemple met en œuvre un gestionnaire d'exceptions personnalisé basé sur le code d'état HTTP renvoyé par la requête GET. Le workflow détecte une exception potentielle et renvoie un message d'erreur prédéfini. Si une exception n'est pas reconnue, l'exécution du workflow échoue et génère l'exception renvoyée par la requête GET. Pour les autres balises d'erreur, consultez la section Erreurs de workflow.

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

Étapes suivantes