Use a header as an object key in Apollo Connector Mapping?

I need to use a header value AcceptLanguage as a reference for a key value in a mapping response.

Given the following REST response

{
  "data": {
    "item": {
      "details": {
        "latest": {
          "variation": {
            "id": "args id",
            "props": [
              {
                "key": "variant-name",
                "val": {
                  "en-US": "en us version of the val"
                }
              }
            ]
          }
        }
      }
    }
  }
}

And the following variables

{
  "$args": {
    "id": "arg id"
  },
  "$this": {
    "headers": {
      "AcceptLanguage": "en-US"
    }
  }
}

And the following mapping

$.data.item.details.latest.variation {
  id
  props -> first.val {
    key: $this.headers.AcceptLanguage
  }
}

I currently get the following response

{
  "id": "args id",
  "key": "en-US"
}

However, I am wanting it to be

{
  "id": "args id",
  "key": "en us version of the val"
}

How can I use the header as a reference to a specific field in the response object?

Things I have tried:

$.data.item.details.latest.variation {
  id
  props -> first.val {
    key: $($this.headers.AcceptLanguage)
  }
}

results in

{
  "id": "args id",
  "key": "en-US"
}
$.data.item.details.latest.variation {
  id
  props -> first.val {
    key: "$($this.headers.AcceptLanguage)"
  }
}

fails with error Property ."$($this.headers.AcceptLanguage)" not found in object

In a related question, I actually need to have the header be Accept-Language, but I haven’t been able to figure out how to escape the - character.

Hey @andywgarcia !

So this is absolutely something we want you to be able to do and is on our roadmap! Specifically, a get method is on our proposed list of arrow methods:

key: $->get($this.headers.AcceptLanguage)

Or a more simple example:

$->echo({"a": "hello"})->get("a") 

Additionally, we’re looking at making a new $request.headers.* variable available as well which may also fit your use case better if you’d like to take request headers and use them for response mapping.

Just replying to add that a possible workaround, if you know all the languages ahead of time, would be to use match. Not ideal but might get you through until we have better options!

$.data.item.details.latest.variation {
  id
  props -> first.val {
    key: $this.headers.AcceptLanguage->match(
      ["en-US", $.'en-US']
     # ... etc
    )
  }
}

Thank you!

This workaround will do for now.

We are definitely looking forward to the ->get function

For reference of the second part of the question of AcceptLanguage vs Accept-Language, it works by just wrapping it in quotes

$this.headers."Accept-Language"

2 Likes

Actually, after putting this in the schema (rather than using it in the playground), there appears to be a discrepancy between the two.

$this.headers does not work in the live schema, but it does not work when composing with rover dev

Hey Andy, what is $this.headers? The $this variable refers to the type the connector is attached to — does your type have a headers field?

This is both mine and ChatGPTs misunderstanding of the mapping. Before I learned that accessing headers from the selection was not a feature that is available yet, it was thought to be the place where I can access header values.

That explains it! As Andrew mentioned, we’re planning to support $request and $response variables in the mapping to provide access to headers. It’s partially implemented and should be available in the coming months!