Key-Value Pairs in GraphQL


Today I was pair programming with a member of my team on a new GraphQL mutation. We were trying to figure out how to represent the returning of data which included a list of key-value pairs – aka a Map datatype. These pairs weren’t constant since they were being returned from a third-party API, so hardcoding the key names in a type wouldn’t work.

We toyed around with the idea of using an array where the first value would represent the key, and the second value would represent the value. We also wondered if the key-value would best be represented as its own type – that way the array method would never be misconstrued.

We ended up delaying our decision to choose one method over another by mocking out what the resulting mutation response would look like to the caller. For example, here’s what the response would look like for using arrays to represent the key-value pairs:

{
  "data": {
    "fields": [
      ["key1", "value1"],
      ["key2", "value2"],
      ["key3", "value3"],
    ]
  }
}

And here’s what the response would look like if a GraphQL type was used for holding key-value pairs:

{
  "data": {
    "fields": [
      {"key": "key1", "value": "value1"},
      {"key": "key2", "value": "value2"},
      {"key": "key3", "value": "value3"}
    ]
  }
}

We quickly realized that the array-based method has the disadvantage of the client needing to implicitly know which place in the array the key and value reside. There’s also possibility of more or less than two elements in the array, even though the user would expect there to be only two. GraphQL and its schema provides a concise and explicit contract, and using this array method bypasses this benefit.

Therefore, we went forth with adding a generic PairType to our GraphQL app. This worked perfectly for our use case.

But now this begs the question: why doesn’t the GraphQL spec support key-value pairs as a first-class type?

It appears that it’s a long standing feature request.