Search code examples
google-workflows

Access HTTP response data saved in a variable with colon


I'm using Google Cloud Workflow to call via http.get a CloudRun app that returns a XML document that has been converted to json, the below json gets successfully returned to Workflow in Step 2 which contains the converted XML to json in the body.

{
  "body": {
    "ResponseMessage": {
      "@xmlns": "http://someurl.com/services",
      "Response": {
        "@xmlns:a": "http://someurl.com/data",
        "@xmlns:i": "http://www.w3.org/2001/XMLSchema-instance",
        "a:ReferenceNumber": {
          "@i:nil": "true"
        },
        "a:DateTime": "2023-01-01T00:17:38+0000",
        "a:TransactionId": "154200432",
        "a:Environment": "Development",
        "a:RequestDateTime": "2023-01-01T11:17:39",            
        }
    },
    "code": 200,
    "headers": {
        "Alt-Svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"",
        "Content-Length": "1601",
        "Content-Type": "application/json",
        "Date": "Sun, 01 Jan 2023 00:17:39 GMT",
        "Server": "Google Frontend",
        "X-Cloud-Trace-Context": "931754ab82102397eb07775171485850"
    }
  }
}

The full yaml of the workflow is below and without step3/step4 it works. In step3 I try to access an element in the json which is returned from step2 as per https://cloud.google.com/workflows/docs/http-requests#access-data

main:
  params: [args]
  steps:
    - step1:
        assign:
          - searchURL: ${"https://myfunction.a.run.app/search/" + args.type + "/" + args.serial}
    - step2:
        call: http.get
        args:
          url: ${searchURL}
        result: s2result
    - step3:
        assign:       
          - resubmitURL: '${https://myfunction.a.run.app/resubmit/" + ${s2result.body.ResponseMessage.Response.a:TransactionId} }'
    - step4:
        call: http.get
        args:
          url: ${resubmitURL}
        result: s4result
    - returnOutput:
        return: ${s4result}

However due to the colon : in the field I'm trying to access there are yaml parsing errors when I attempt to save another variable assignment. How can I access a HTTP response data saved in a variable when there are colons in the property field.

The errors in the console are similar too

    Could not deploy workflow: main.yaml:14:25: parse error: in workflow 'main', step 'step3': token recognition error at: ':'
          - resubmitURL: '${"https://myfunction.a.run.app/resubmit/" + ${s2result.body.ResponseMessage.Response.a:TransactionId}'
                        ^

main.yaml:14:25: parse error: in workflow 'main', step 'step3': mismatched input '+' expecting {'[', LOGICAL_NOT, '(', '-', TRUE, FALSE, NULL, NUM_FLOAT, NUM_INT, STRING, IDENTIFIER}
          - resubmitURL: '${"https://myfunction.a.run.app/resubmit/" + ${s2result.body.ResponseMessage.Response.a:TransactionId}'

Solution

  • Two techniques are required to reference map keys with special characters like this:

    1. As recommended in the documentation, all expressions should be wrapped in single quotes to avoid YAML parsing errors (i.e. '${...}').
    2. When referencing keys with special characters, you can use array notation to wrap the key name in quotes (i.e. var["KEY"]).

    Together, it looks like this:

    main:
        steps:
        - init:
            assign:
            - var:
                key: 
                    "co:lon": bar
        - returnOutput:
            return: '${"foo" + var.key["co:lon"]}'