У меня проблема с ограничением моей конечной точки graphql для обслуживания только тех данных, которые запрашивающий пользователь может запрашивать
я использую
apollo-server 2.1.0
express 4.16.3
graphql 0.13.2
graphql-tools 4.0.0
neo4j-graphql-js 0.2.1
Тип Ярлык имеет поле элементы, которое должно содержать только те элементы, которыми владеет текущий пользователь.
type Tag {
name: String!
elements(username:String): [Element] @cypher(statement: "MATCH (this)-[:TAGGED]-(e:Element)-[:OWNER]-(u:User) WHERE u.name=$username RETURN e")
}
type Element {
uuid: String!
name: String
users: [User] @relation(name:"OWNER", direction:"IN")
tags: [Tag] @relation(name:"TAGGED", direction:"IN")
responses: [Element] @relation(name:"RESPONSE", direction:"OUT")
}
Когда мой запрос выглядит так:
{
Tag{
name,
elements(username:"crmue"){
name
}
}
}
Результат выглядит ожидаемым. Но я хочу проверить и установить аргумент имени пользователя в преобразователе на основе привязанного к контексту пользователя.
Но когда я добавляю следующую строку в корневой распознаватель тегов перед выполнением запроса, мой ответ оказывается пустым.
params['username'] = ctx.user.name;
В этом случае сгенерированный оператор cypher помещает агрумент имени пользователя в раздел корневого тега, а не в раздел дочернего элемента (оператор @cypher). Но я понятия не имею, как установить аргумент имени пользователя для элементов поля Tag в преобразователе до того, как данные будут извлечены.
Так что я надеюсь, что у кого-то есть идея, как решить мою проблему, или есть идея получше, чем мое решение здесь с оператором @cypher.
Спасибо!
ОБНОВИТЬ
Мои текущие базовые преобразователи:
export const resolvers = {
Tag : {
elements : (object, params, ctx, resolveInfo) => {
params["username"] = ctx.user.name;
}
},
Query: {
User(object, params, ctx, resolveInfo) {
return neo4jgraphql(object, params, ctx, resolveInfo);
},
Element(object, params, ctx, resolveInfo) {
return neo4jgraphql(object, params, ctx, resolveInfo);
},
Tag(object, params, ctx, resolveInfo) {
if (!ctx.user){
throw Error("Wrong request");
}
params["username"] = ctx.user.name;
return neo4jgraphql(object, params, ctx, resolveInfo);
},
}
};
Добавление параметра в преобразователь поля 'elements' не имеет никакого эффекта, поскольку преобразователи полей вызываются, когда данные уже получены.
Я пробовал это, но преобразователи полей вызываются, когда данные уже получены. Я могу использовать преобразователь element, чтобы впоследствии отфильтровать полученные данные.





Обычно корневой преобразователь не возвращает весь объект, а только «собственные поля», оставляя связанные поля для обработки преобразователями полей. В этом случае похоже, что neo4jgraphql (я предполагаю, что я не использовал его) достаточно умен, чтобы обрабатывать его полностью на корневом уровне.
Если params["username"] = ctx.user.name; в Tag не работает, то похоже, что neo4jgraphql не заботится о params (IMHO, это должно - проблема?) И работает непосредственно с аргументом info преобразователя (уже существующие переменные).
Попробуйте добавить username в массив variableValues. Пояснения
В этом случае преобразователь поля не требуется.
Второй вариант: удалить elements из fieldNodes (в преобразователе Tag) и использовать преобразователь полей (params / variableValues).
Если проблема не устранена, проверьте / запишите состояние / значения info.
neo4j-graphql-js пытается получить все за один проход в базу данных в корневом преобразователе тегов. Директива @cypher поля elements используется для построения этого единственного зашифрованного оператора. Я решил свою проблему с помощью вашего совета по изменению значений аргументов в информации о восстановлении. Это не совсем удобно, но работает.
Создал проблему на github для neo4j-graphql-js см. ссылка на выпуск №112
использовать
ctx.user.nameнепосредственно в преобразователеelements?