Если у меня есть объект:
{"where":{"publishedAt_lt":"2018-01-01"}}
Как преобразовать его в строку, подходящую для аргументов запроса?
articles(where: {publishedAt_lt: "2018-01-01"})
Это пример. У меня есть простой объект JS, который поступает извне, и мне нужно преобразовать его в аргумент gql
Вы можете опубликовать свой полный запрос



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


это не ответ на ваш вопрос, но ваш вопрос обычно не возникает, если вы следуете лучшим практикам: запросы 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, обратитесь к своей клиентской библиотеке. Я уверен, что у них есть раздел документации по этому поводу. Для react-apollo вы можете найти документацию о том, как передавать переменные здесь.
да, у меня есть допустимый вариант использования: преобразование переменных в преобразователях серверов, построенных поверх другого хоста graphql
Похоже, это интересная библиотека, я бы посоветовал ее проверить:
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
}
}
}
}`
} );
При этом я собираюсь проверить упомянутую библиотеку и, вероятно, использовать ее в дальнейшем.
Это более сложная задача со множеством нюансов. Я знаю эту библиотеку - я внес в нее свой вклад. На самом деле был мой собственный ответ на этот вопрос со ссылкой на эту библиотеку, но модератор stackoverflow.com/users/4099593/bhargav-rao удалил ее без причины
Попробуй это:
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"}}
Я взял подход KMcAloon и сделал его также поддерживающим массив. Таким образом, вы можете полностью сделать свой запрос как объект и на последнем шаге обернуть его => например
mutation createPackage {
createPackage(
data: ${queryfy(data)}
) {
name
_id
})
}
/**
* 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;
}
if (Array.isArray(obj)) {
const props = obj.map(value => `${queryfy(value)}`).join(',');
return `[${props}]`;
}
if (typeof obj === 'object') {
const props = Object.keys(obj)
.map(key => `${key}:${queryfy(obj[key])}`)
.join(',');
return `{${props}}`;
}
return JSON.stringify(obj);
};
Это именно то, что у вас уже есть? Кавычки вокруг ключа (в данном случае) не имеют смысла.