Can GraphQL handle XML responses where single item arrays are converted to dictionaries?

Can GraphQL handle XML responses where single item arrays are converted to dictionaries?


2

I’m currently working on a GraphQL/Node/Express server that retrieves data from another API. I have absolutely no access to the other API except for the data I receive back.

My problem is that the response is XML and there are certain fields that should be returned as arrays but instead are being returned as objects (or dictionaries) if the array has only one item in it.

This blog post explains the issue in more detail.

Is there a way in GraphQL to design the schema in such a way that if it receives an object for a property that is defined as an array, that it places the object into an array?

Examples

Current behaviour

<team>
  <employee>
    <name>Joe</name>
    <surname>Bloggs</surname>
  </employee>
  <employee>
    <name>Jane</name>
    <surname>Doe</surname>
  </employee>
</team>

The above XML will convert to JSON as below

{
  team:{
    employee:[
      {
        name:'Joe',
        surname:'Bloggs'
      },
      {
        name:'Jane',
        surname:'Doe'
      }
    ]
  }
}

But if there is only one employee

<team>
  <employee>
    <name>Joe</name>
    <surname>Bloggs</surname>
  </employee>
</team>

The above XML will convert to JSON as below, where employee becomes an object rather than an array

{
  team:{
    employee:{
      name:'Joe',
      surname:'Bloggs'
    }
  }
}

2 Answers
2


3

Yes, it’s possible and easy to implement

With Apollo you define resolver maps that will be used to resolve all the fields and sub fields of your types, for queries and mutations.

Read about resolvers

In your case, you could write a resolver for the specific field employee on the Team type, that will make sure to return an array.

{ 
  Team: {
   employee(parentObject, args, context) {
     const {employee} = parentObject
         // you should probably handle the case when employee is null or undefined
     return Array.isArray(employee) ? employee : [employee]
   }
  ...
}

The result will be:

{
  team: {
    employee: [
      {
        name:'Joe',
        surname:'Bloggs'
      }
    ]
  }
}

Note: you don’t have to implement all the resolver functions by yourself. If you did not provide a resolver function for a field, Apollo will use a default resolver. That usually means simply returning the value as it is.


0

you can use "force_list=(’employee’,) when you call that API, assuming you are aware of which fields will throw this issue. This will make sure it is always converted to list even if one object is present.

New contributor

Ritaja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



Leave a Reply

Your email address will not be published. Required fields are marked *