Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GraphQL: build query arguments from object

If I have an object:

{"where":{"publishedAt_lt":"2018-01-01"}}

How can I convert it to a string suitable for query arguments?

articles(where: {publishedAt_lt: "2018-01-01"})
like image 227
Terion Avatar asked Mar 07 '23 02:03

Terion


1 Answers

This looks like an interesting library, I would suggest checking it out:

https://www.npmjs.com/package/json-to-graphql-query

But basically all we need to do is to convert the object to a string while ensuring the keys do not adopt double quotes and integers are not converted into strings, as that might not play well with the graphql schemas we're working with.

Since JSON.stringify() won't accomplish this, I came up with this little function to help with interpolating arguments into my queries:

/**
 * Queryfy.
 *
 * Prep javascript objects for interpolation within graphql queries.
 *
 * @param {mixed} obj
 * @return template string.
 */
const queryfy = obj => {

  // Make sure we don't alter integers.
  if( typeof obj === 'number' ) {
    return obj;
  }

  // Stringify everything other than objects.
  if( typeof obj !== 'object' || Array.isArray( obj ) ) {
    return JSON.stringify( obj );
  }

  // Iterate through object keys to convert into a string
  // to be interpolated into the query.
  let props = Object.keys( obj ).map( key =>
    `${key}:${queryfy( obj[key] )}`
  ).join( ',' );

  return `{${props}}`;

}

Here is a reduced portion of my code where I am using this successfully:

const dateQuery = {};

if( !! date1 ) {

  dateQuery.after = {
    year: parseInt( date1.format( 'YYYY' ) ),
    month: parseInt( date1.format( 'M' ) ),
    day: date1.format( 'D' ) - 1,
  }

}
if( !! date2 ) {

  dateQuery.before = {
    year: parseInt( date2.format( 'YYYY' ) ),
    month: parseInt( date2.format( 'M' ) ),
    day: date2.format( 'D' ) - 1,
  }

}

const query = await client.query( {
  query: gql `{
    apiResponses( where: {
      dateQuery: ${queryfy( dateQuery )}
    } ) {
      edges {
        node {
          apiResponseId
          title
          date
          json
        }
      }
    }
  }`
} );

That being said, I am going to check out the library mentioned and probably use that moving forward.

like image 111
KMcAloon Avatar answered Mar 15 '23 18:03

KMcAloon