NodeJs GraphQL 枚举类型值作为动态

Posted

技术标签:

【中文标题】NodeJs GraphQL 枚举类型值作为动态【英文标题】:NodeJs GraphQL enum type value as dynamic 【发布时间】:2018-04-08 18:07:01 【问题描述】:

https://launchpad.graphql.com/9qvqz3v5r

这是我的示例 graphQL Schema。我正在尝试使用枚举类型。如何从后端获取枚举值并将其提供给架构?

// Construct a schema, using GraphQL schema language
const typeDefs = `
  type User 
        userId: Int
        firstName: String
        lastName: String
        pincode:String
        state:String
        country:String
  
  type Query 
    hello: String
    user: User
  
  type CreateUserLoad 
    user: User 
  
  enum Role 
        writer
        reader
        author
        admin
        superAdmin
  
  type Mutation
        createUser(firstName: String, lastName: String, role: Role): User
  
`;

我想将动态变量中的 enum Role 值填充为

const roleData = ['writer','reader','author','admin','superAdmin'];

谁能帮帮我?

【问题讨论】:

您找到解决方案了吗?接受的答案对我不起作用。由于我的架构是在 .graphql 文件中定义的,因此我无法在其中注入外部变量。仍在寻找解决方案 【参考方案1】:

你可以简单地使用字符串插值:

// Construct a schema, using GraphQL schema language
const typeDefs = `
  type User 
        userId: Int
        firstName: String
        lastName: String
        pincode:String
        state:String
        country:String
  
  type Query 
    hello: String
    user: User
  
  type CreateUserLoad 
    user: User 
  
  enum Role  $roles.join(' ') 
  type Mutation
        createUser(firstName: String, lastName: String, role: Role): User
  
`;

事实上,在每个传入的 grahpql 查询中,您都必须将解析后的模式传递给 graphql 服务器,因此您甚至可以为每个请求更改它。在这种情况下,最好更改模式解析返回的对象表示。

对于直接创建枚举类型,假设您有一个值数组 userRoles 并想要一个 RolesEnum 类型,那么您可以像这样创建它:

const roleValues = 
for (const value of userRoles) 
    roleValues[value] = value

const RolesEnum = new GraphQLEnumType(
    name: 'UserRoles',
    values: roleValues,
)

然后您可以将其直接分配为架构中的类型。

【讨论】:

“事实上,在每个传入的 grahpql 查询中,您必须将解析后的模式传递给 graphql 服务器,因此您甚至可以为每个请求更改它。”您不能认真地建议他为每个请求解析方案吗? 解析架构后,您就有了对象表示,您可以更改它。 你是对的,但这不是你的例子所暗示的。如果您想用这个新示例更改您的答案,我可以将我的 -1 替换为 +1。 @zoran404 类似吗? @w00t 好吧,您没有提供如何在架构对象中设置枚举值的示例,因此我认为您的答案没有用,但我将删除 -1。我明白为什么您不想为此编写示例而烦恼,因为您需要为每个枚举值生成新的 astNode 或使用解析器来生成它。这两种解决方案都可能需要一段时间才能弄清楚。【参考方案2】:

如果您的枚举值是从database 或任何其他后端源加载的,或者如果枚举列表是dynamic,则您的架构中不能有static 枚举定义。

动态设置枚举的最大问题是您的架构是后端和前端之间的契约,并且不应该被更改。

如果您打算将角色用作任意字符串,则将其定义为这样!

type Mutation 
  createUser(firstName: String, lastName: String, role: String): User

这里唯一的区别是您的解析器必须检查角色是否存在,这是 graphql 之前在您使用枚举时为您所做的。

或者

如果角色用于大量查询/突变,您可以定义一个 scalar Role 并在标量的解析中检查角色是否存在,如果不存在则简单地抛出错误。

在这种情况下,您的突变看起来就像您有一个动态的enum Role,但您根本不需要更改架构。

type Mutation 
  createUser(firstName: String, lastName: String, role: Role): User

【讨论】:

【参考方案3】:

使用字符串插值添加动态枚举和文档字符串。

示例:我有一个国家列表及其 ISO2 代码

const countryData = [
   name:'India', code: 'IN',
   name:'Afghanistan', code: 'AF',
   name:'Algeria', code: 'DZ',
   name: 'Ireland', code: 'IE'
];

const countryCodes = countryData.flatMap(country => [
  `"$country.name"`,
  country.code
]);

不使用Array.join()


enum CountryCode  $countryCodes 

【讨论】:

以上是关于NodeJs GraphQL 枚举类型值作为动态的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL 是不是将 Int 作为枚举

如何在 apollo graphQL 服务器的枚举值中添加特殊字符?

将枚举类型作为参数传递给 GraphQL 查询 - Quarkus

NodeJs GraphQL 动态查询变量

在方法的参数中使用动态枚举作为类型

如何在graphql中获取所有枚举值