2017-06-19 41 views
2

比方说,我有一个包含以下字段的用户类型:GraphQL:如何跨服务器端查询字段?

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%相似形成彼此。

是否有一个更清晰的方式来实现这一点,它不会创建不必要的类型或重复的字段?

回答

3

默认情况下,GraphQL类型可能是类型,这意味着您可以将null返回到任何字段。

这意味着,在creditCardNumber字段的resolve函数中,您可以检查当前用户是否被抓取,如果是,则返回该数字。否则,你返回null。

要访问“contexted”数据,如当前用户,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

+0

非常感谢! –

+0

我不敢相信这必须在需要过滤的每个领域的解决方案中处理。 –