假设我的用户类型包含以下字段:
type User {
name: String
username: String
someOtherField1: String
someOtherField2: String
someOtherField3: String
someOtherField4: String
creditCardNumber: String
}
如果我自己查询,可以返回所有字段,因为信息是我的。所以将creditCardNumber
返回给客户端并不重要。但是,如果我要查询其他人,我应该只能访问返回用户的公共信息。返回creditCardNumber
会很糟糕。即使我不在客户端上编写查询代码,也会阻止恶意用户深入挖掘代码,更新客户端查询以包含creditCardNumber
并执行它?
在GraphQL中跨查询实现此级别字段限制的最佳方法是什么?到目前为止,我唯一想到的是创建一个单独的UserSearch
类型,即
type UserSearch {
name: String
username: String
someOtherField1: String
someOtherField2: String
someOtherField3: String
someOtherField4: String
}
排除了私有字段,但是这并不感觉干,因为你要创建许多结构形式相似90%的类型。
是否有更简洁的方法来实现这一点,不会创建不必要的类型或重复字段?
答案 0 :(得分:13)
默认情况下,GraphQL类型可能是类型,这意味着您可以将null返回到任何字段。
这意味着,在resolve
字段的creditCardNumber
函数内,您可以检查当前用户是否是被提取的用户,如果是,则返回该数字。否则,返回null。
要访问“上下文”数据(如当前用户),GraphQL允许您在执行graphql函数时传递对象context
:
graphql(schema, query, rootValue, context) // <-- the last parameter
您将在每个字段resolve
函数签名中找到此对象:
...
resolve: (object, args, context) => {
// Third argument is your object
},
....
所以你可以做的是在上下文中传递当前记录的用户:
graphql(schema, query, rootValue, { user: getCurrentLoggedUser() })
在您的User
类型中,creditCardNumber
字段解析功能:
creditCardNumber: {
...
resolve: (user, args, context) => {
if (user.id === context.user.id)
return user.creditCardNumber;
return null;
},
...
}
如果您使用的是graphql-express
,则默认情况下上下文是and you can customize it。