GraphQL: построить аргументы запроса из объекта - PullRequest
0 голосов
/ 02 июня 2018

Если у меня есть объект:

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

Как я могу преобразовать его в строку, подходящую для аргументов запроса?

articles(where: {publishedAt_lt: "2018-01-01"})

Ответы [ 3 ]

0 голосов
/ 19 января 2019

Это похоже на интересную библиотеку, я бы посоветовал проверить ее:

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

Но в основном все, что нам нужно сделать, - это преобразовать объект в строку, обеспечивая при этомключи не принимают двойные кавычки, а целые числа не преобразуются в строки, так как это может не очень хорошо сочетаться со схемами graphql, с которыми мы работаем.

Так как JSON.stringify () этого не сделает, я придумал эту маленькую функцию, чтобы помочь с интерполяцией аргументов в мои запросы:

/**
 * 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}}`;

}

Вот уменьшенная часть моегокод, в котором я успешно использую это:

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
        }
      }
    }
  }`
} );

При этом я собираюсь проверить упомянутую библиотеку и, вероятно, использовать ее для продвижения вперед.

0 голосов
/ 23 января 2019

Попробуйте это:

const { where } = {"where":{"publishedAt_lt":"2018-01-01"}}
articleList = articles({where}) // assume articles takes an object - equivalent to articles({where: where}) or articles({where: {publishedAt_lt: "2018-01-01"}}
0 голосов
/ 03 июня 2018

это не ответ на ваш вопрос, но ваш вопрос обычно не должен возникать, если вы следуете передовым методам: запросы GraphQL должны быть статическими - это означает, что вы не генерируете их из переменных ввода.Может быть, у вас есть действительный вариант использования для этого, но я едва ли могу себе это представить.Пожалуйста, дайте мне знать в комментариях.

Когда ваш клиент имеет переменную для ввода аргумента поля, вы хотите использовать вместо нее переменные:

query getArticles($filter: ArticlesFilter) { # Please insert your input type name
  articles(where: $filter) {
    # ...
  }
}

Затем вы можете передать эти данные вполе переменных запроса:

let givenObject = {"where":{"publishedAt_lt":"2018-01-01"}}; // said object
fetch('/graphql', {
  method: 'POST',
  body: JSON.stringify({
    query, // put the query string from above
    variables: {
      filter: givenObject,
    },
  }),
});

Теперь это простой JS, пожалуйста, обратитесь к вашей клиентской библиотеке.Я уверен, что у них есть раздел документации об этом.Для реакции-аполлона вы можете найти документы, как передавать переменные здесь .

...